-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
경북대_Android_이혜원 1주차 과제 #3
base: main
Are you sure you want to change the base?
Changes from all commits
926f22c
0cacff4
4aa7b8b
844d341
0cd276e
1242355
f594f39
d465051
303522b
faef309
3b3e7f4
91850c4
1a09a6b
0345d82
a0842d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,44 @@ | ||
# android-contacts | ||
|
||
Step1 : 연락처 추가 | ||
|
||
[제시된 기능요구사항] | ||
|
||
[목표] | ||
: 간단한 연락처를 구현한다. | ||
* 연락처를 추가한다. | ||
* 이름과 전화번호는 필수 값이다. | ||
* 입력하지 않으면 토스트 메시지를 보여준다. | ||
* 전화번호 입력은 숫자만 가능하다. | ||
* 더보기를 눌러 입력 폼을 확장할 수 있다. | ||
* 생일, 성별, 메모 입력 폼이 등장한다. | ||
* 성별을 둘 중 하나를 선택할 수 있다. | ||
* 저장 버튼을 누르면 '저장이 완료 되었습니다' 라는 토스트 메시지를 보여준다. | ||
* 취소 버튼을 누르면 '취소 되었습니다' 라는 토스트 메시지를 보여준다. | ||
|
||
[나누어진 커밋 단계] | ||
1. doc : ReadMe 파일 추가 | ||
2. feat : 레이아웃 추가 (UI추가) | ||
3. feat : 이름과 전화번호를 입력하지 않을시 토스트 메시지 보내기 구현 | ||
4. feat :더보기를 누를시, 입력폼 확장 구현 | ||
5. feat : 이름과 전화번호를 누를시, ‘저장완료’ 토스트 메시지 보내기 구현 | ||
6. feat : 취소 버튼을 누를시, ‘취소완료’ 토스트 메시지 보내기 구현 | ||
|
||
|
||
Step2 : 연락처 목록 | ||
|
||
[제시된 기능 요구 사항] | ||
목표 : 간단한 연락처를 구현한다. | ||
|
||
연락처 등록 화면을 구현한다. | ||
연락처를 저장하면 목록에 추가된다. | ||
저장된 연락처가 많을 경우 목록은 스크롤 되어야 한다. | ||
추가된 연락처를 선택하여 상세 화면을 볼 수 있다. | ||
연락처 작성 중 뒤로가기 버튼을 누르면 확인 팝업이 나타난다. | ||
추가된 연락처는 앱을 다시 실행하면 유지되지 않는다. | ||
|
||
1. 연락처 등록 화면 구현 | ||
2. 연락처 저장시, 목록에 추가 기능 구현 | ||
3. 목록 화면 구현 | ||
4. 연락처 목록에서 상세페이지 화면 구현 | ||
5. 상세페이지 보기 기능 구현 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.util.Log | ||
import androidx.lifecycle.MutableLiveData | ||
import androidx.lifecycle.ViewModel | ||
|
||
class ContactViewModel : ViewModel() { | ||
val contactListLiveData = MutableLiveData<MutableList<contact>>().apply { | ||
value = ContactList | ||
} | ||
|
||
fun addContact(contact: contact) { | ||
ContactList.add(contact) | ||
contactListLiveData.value = ContactList | ||
Log.d("ContactViewModel", "Contact added: ${contact.name}, total contacts: ${ContactList.size}") | ||
} | ||
} | ||
Comment on lines
+7
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MVVM은 안쓰기로 하지 않았나요~? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.os.Bundle | ||
import androidx.appcompat.app.AppCompatActivity | ||
import campus.tech.kakao.contacts.databinding.ActivityDetailContactBinding | ||
|
||
class DetailContact : AppCompatActivity() { | ||
private lateinit var binding: ActivityDetailContactBinding | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
binding = ActivityDetailContactBinding.inflate(layoutInflater) | ||
setContentView(binding.root) | ||
|
||
// Intent로부터 데이터를 받아와서 UI에 설정 | ||
val name = intent.getStringExtra("name") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보통 이런 요소는 Constant라는 object를 파일단위로 생성하고 |
||
val phoneNumber = intent.getStringExtra("phoneNumber") | ||
|
||
binding.Name.text = name | ||
binding.TelePhone.text = phoneNumber | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.util.Log | ||
import android.widget.ImageButton | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.databinding.DataBindingUtil | ||
import campus.tech.kakao.contacts.databinding.ActivityListBinding | ||
|
||
class ListActivity : AppCompatActivity() { | ||
private lateinit var binding: ActivityListBinding | ||
private val contactViewModel: ContactViewModel by viewModels() | ||
private lateinit var adapter: ListViewAdapter | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
|
||
binding = DataBindingUtil.setContentView(this, R.layout.activity_list) | ||
val plusButton: ImageButton = findViewById(R.id.PlusButton) | ||
|
||
initListView() | ||
|
||
plusButton.setOnClickListener { | ||
val intent = Intent(this, MainActivity::class.java) | ||
startActivity(intent) | ||
} | ||
} | ||
|
||
override fun onResume() { | ||
super.onResume() | ||
handleIncomingIntent() | ||
} | ||
|
||
private fun initListView() { | ||
adapter = ListViewAdapter() | ||
binding.listView.adapter = adapter | ||
|
||
contactViewModel.contactListLiveData.observe(this) { contactList -> | ||
adapter.notifyDataSetChanged() | ||
} | ||
} | ||
|
||
private fun handleIncomingIntent() { | ||
val name = intent.getStringExtra("name") ?: "" | ||
val phoneNumber = intent.getStringExtra("phoneNumber") ?: "" | ||
|
||
if (name.isNotEmpty() && phoneNumber.isNotEmpty()) { | ||
Log.d("ListActivity", "New contact: $name, $phoneNumber") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코드를 업로드하기전엔 로그를 되도록 지워주세요. |
||
contactViewModel.addContact(contact(name, name[0].toString(), phoneNumber)) | ||
// Intent 데이터를 초기화하여 중복 추가 방지 | ||
intent.removeExtra("name") | ||
intent.removeExtra("phoneNumber") | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.content.Intent | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.widget.BaseAdapter | ||
import campus.tech.kakao.contacts.databinding.ContactListBarBinding | ||
|
||
class ListViewAdapter : BaseAdapter() { | ||
|
||
override fun getCount(): Int = ContactList.size | ||
|
||
override fun getItem(position: Int): contact = ContactList[position] | ||
|
||
override fun getItemId(position: Int): Long = position.toLong() | ||
|
||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { | ||
val binding: ContactListBarBinding | ||
val view: View | ||
|
||
if (convertView == null) { | ||
binding = ContactListBarBinding.inflate(LayoutInflater.from(parent.context), parent, false) | ||
view = binding.root | ||
view.tag = binding | ||
} else { | ||
binding = convertView.tag as ContactListBarBinding | ||
view = convertView | ||
} | ||
|
||
val contact = getItem(position) | ||
binding.NameSpace.text = contact.name | ||
binding.OneNameSpace.text = contact.oneName | ||
binding.TeleSpace.text = contact.phone_number | ||
|
||
// 아이템 클릭 리스너 설정 | ||
view.setOnClickListener { | ||
val context = parent.context | ||
val intent = Intent(context, DetailContact::class.java).apply { | ||
putExtra("name", contact.name) | ||
putExtra("phoneNumber", contact.phone_number) | ||
} | ||
context.startActivity(intent) | ||
} | ||
|
||
return view | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,71 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.content.DialogInterface | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.view.View | ||
import android.widget.EditText | ||
import android.widget.TextView | ||
import android.widget.Toast | ||
import androidx.appcompat.app.AlertDialog | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.appcompat.widget.LinearLayoutCompat | ||
|
||
class MainActivity : AppCompatActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.activity_main) | ||
|
||
val nameEdit: EditText = findViewById(R.id.NameEdit) | ||
val phoneNumberEdit: EditText = findViewById(R.id.PhoneNumberEdit) | ||
val moreText: TextView = findViewById(R.id.MoreText) | ||
val birthEdit: EditText = findViewById(R.id.BirthEdit) | ||
val memoEdit: EditText = findViewById(R.id.MemoEdit) | ||
val genderArea: LinearLayoutCompat = findViewById(R.id.GenderArea) | ||
val saveText: TextView = findViewById(R.id.SaveText) | ||
val cancelText: TextView = findViewById(R.id.CancleText) | ||
Comment on lines
+19
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메소드를 실행시킬때마다 비싼 xml 파싱을 통해 뷰를 탐색해내는 findViewBy 를 실행하는 것이 아닌, |
||
|
||
moreText.setOnClickListener { | ||
moreText.visibility = View.GONE | ||
birthEdit.visibility = View.VISIBLE | ||
memoEdit.visibility = View.VISIBLE | ||
genderArea.visibility = View.VISIBLE | ||
} | ||
|
||
saveText.setOnClickListener { | ||
val name = nameEdit.text.toString().trim() | ||
val phoneNumber = phoneNumberEdit.text.toString().trim() | ||
|
||
if (name.isEmpty()) { | ||
Toast.makeText(this@MainActivity, "이름은 필수값입니다.", Toast.LENGTH_SHORT).show() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 String은 |
||
} else if (phoneNumber.isEmpty()) { | ||
Toast.makeText(this@MainActivity, "전화번호는 필수값입니다.", Toast.LENGTH_SHORT).show() | ||
} else { | ||
Toast.makeText(this@MainActivity, "저장되었습니다.", Toast.LENGTH_SHORT).show() | ||
|
||
val intent = Intent(this, ListActivity::class.java).apply { | ||
putExtra("name", name) | ||
putExtra("phoneNumber", phoneNumber) | ||
} | ||
startActivity(intent) | ||
finish() | ||
Comment on lines
+46
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. navigateToContactListView() 이런 함수로 감싸는것도 좋아보이네요. |
||
} | ||
} | ||
|
||
cancelText.setOnClickListener { | ||
Toast.makeText(this@MainActivity, "취소되었습니다.", Toast.LENGTH_SHORT).show() | ||
finish() | ||
} | ||
} | ||
|
||
override fun onBackPressed() { | ||
// 확인 다이얼로그 표시 | ||
AlertDialog.Builder(this) | ||
.setMessage("작성을 취소하시겠습니까?") | ||
.setPositiveButton("예") { dialog, which -> | ||
super.onBackPressed() | ||
} | ||
.setNegativeButton("아니오", null) | ||
.show() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.widget.ImageButton | ||
import androidx.appcompat.app.AppCompatActivity | ||
|
||
class PlusActivity : AppCompatActivity() { | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.plus_screen) | ||
|
||
var PlusButton : ImageButton = findViewById(R.id.PlusButton) | ||
|
||
val intent = Intent(this,MainActivity::class.java) | ||
PlusButton.setOnClickListener{ | ||
startActivity(intent) | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package campus.tech.kakao.contacts | ||
|
||
var ContactList: MutableList<contact> = mutableListOf() | ||
|
||
data class contact( | ||
val name: String, | ||
val oneName: String, | ||
val phone_number: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp"> | ||
|
||
<path android:fillColor="@android:color/white" android:pathData="M16.84,14.52c-0.26,-0.19 -0.62,-0.63 -0.79,-0.84C17.24,12.01 19,8.87 19,5c0,-1.95 -0.74,-3 -2,-3c-1.54,0 -3.96,2.06 -5,5.97C10.96,4.06 8.54,2 7,2C5.74,2 5,3.05 5,5c0,3.87 1.76,7.01 2.95,8.68c-0.17,0.21 -0.53,0.65 -0.79,0.84c-0.5,0.41 -1.66,1.37 -1.66,2.98c0,2.21 1.79,4 4,4c1.55,0 2.5,-0.56 2.5,-0.56s0.95,0.56 2.5,0.56c2.21,0 4,-1.79 4,-4C18.5,15.89 17.34,14.93 16.84,14.52zM9.35,12.2C8.34,10.7 7,8.12 7,5c0,-0.49 0.06,-0.8 0.12,-0.97c0.94,0.31 3.24,2.71 3.38,7.64C10.03,11.79 9.66,11.97 9.35,12.2zM10.5,16.75c-0.28,0 -0.5,-0.34 -0.5,-0.75c0,-0.41 0.22,-0.75 0.5,-0.75S11,15.59 11,16C11,16.41 10.78,16.75 10.5,16.75zM12,19.5c-0.55,0 -1,-0.72 -1,-1c0,-0.28 0.45,-0.5 1,-0.5s1,0.22 1,0.5C13,18.78 12.55,19.5 12,19.5zM13.5,16.75c-0.28,0 -0.5,-0.34 -0.5,-0.75c0,-0.41 0.22,-0.75 0.5,-0.75S14,15.59 14,16C14,16.41 13.78,16.75 13.5,16.75zM13.5,11.67c0.14,-4.93 2.44,-7.33 3.38,-7.64C16.94,4.2 17,4.51 17,5c0,3.12 -1.34,5.7 -2.35,7.2C14.34,11.97 13.97,11.79 13.5,11.67z"/> | ||
|
||
</vector> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
두개의 차이는 무엇이며, 두개를 왜 꼭 같이 써야할까요~?