diff --git a/README.md b/README.md index cc0acc5a..e4037b97 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ # android-contacts +## 기능 목록 +### step1 +- 연락처 정보 입력하기 + - 이름: 필수-Toast 메세지(이름을 입력해주세요.) + - 전화번호 + - 필수-Toast 메세지(전화번호를 입력해주세요.) + - 숫자만 가능-Toast 메세지(전화번호는 숫자로만 입력해주세요.) + - 메일 + - 더보기 + - 클릭하면 입력 폼이 확장된다. + - 생일: 캘린더 + - 성별: 여자, 남자 중에 선택한다. + - 메모 +- 저장하기 + - Toast(저장이 완료되었습니다.) +- 취소하기 + - Toast(취소되었습니다.) + +### step2 +- 연락처 목록 + - 이름 앞글자가 적힌 사진과 이름 정보가 나타난다. + - 스크롤이 가능하다. +- 연락처 추가 + - 추가 도중 취소하면 확인 팝업이 나타난다. + - 추가가 완료되면 Toast(저장이 완료되었습니다.) +- 연락처 상세 보기 + - 이름과 전화번호 정보가 나타난다. \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c5add08f..d751bb40 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -41,6 +41,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.11.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("androidx.activity:activity:1.9.0") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 89dc9d8b..b30ecb49 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,13 @@ android:theme="@style/Theme.Contacts" tools:targetApi="31"> + + @@ -23,4 +29,4 @@ - + \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/contacts/ContactAddActivity.kt b/app/src/main/java/campus/tech/kakao/contacts/ContactAddActivity.kt new file mode 100644 index 00000000..69f20cd7 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/contacts/ContactAddActivity.kt @@ -0,0 +1,98 @@ +package campus.tech.kakao.contacts + +import android.app.DatePickerDialog +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.Button +import android.widget.EditText +import android.widget.RadioGroup +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.LinearLayoutCompat +import java.util.Calendar + +class ContactAddActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + val name_input: EditText = findViewById(R.id.name_input) + val phone_number_input: EditText = findViewById(R.id.phone_number_input) + val email_input: EditText = findViewById(R.id.email_input) + + val birth_date_input: EditText = findViewById(R.id.birth_date_input) + val birth_date_radiogroup: RadioGroup = findViewById(R.id.birth_date_radiogroup) + + val gender_input: EditText = findViewById(R.id.gender_input) + val memo_input: EditText = findViewById(R.id.memo_input) + + val save_button: Button = findViewById(R.id.save_button) + val cancel_button: Button = findViewById(R.id.cancel_button) + val see_more_button: LinearLayoutCompat = findViewById(R.id.see_more_button) + val see_more_input_form: LinearLayoutCompat = findViewById(R.id.see_more_input_form) + + see_more_input_form.visibility = View.GONE + birth_date_input.setClickable(false) + birth_date_input.setFocusable(false) + gender_input.setClickable(false) + gender_input.setFocusable(false) + + see_more_button.setOnClickListener{ + see_more_button.visibility = View.GONE + see_more_input_form.visibility = View.VISIBLE + } + + birth_date_input. setOnClickListener{ + var calendar = Calendar.getInstance() + var year = calendar.get(Calendar.YEAR) + var month = calendar.get(Calendar.MONTH) + var day = calendar.get(Calendar.DAY_OF_MONTH) + this.let { it1 -> + DatePickerDialog(it1, { _, year, month, day -> + run { + birth_date_input.setText(year.toString() + "." + (month + 1).toString() + "." + day.toString()) + } + }, year, month, day) + }?.show() + } + + birth_date_radiogroup.run { + setOnCheckedChangeListener { group, checkedId -> + when(checkedId){ + R.id.woman_radiobutton -> {gender_input.setText("여성")} + R.id.man_radiobutton -> {gender_input.setText("남성")} + } + } + } + + save_button.setOnClickListener { + if (name_input.text.isNullOrEmpty()) { + Toast.makeText(this, "이름을 입력해주세요.", Toast.LENGTH_SHORT).show() + } + else if (phone_number_input.text.isNullOrEmpty()) { + Toast.makeText(this, "전화번호를 입력해주세요.", Toast.LENGTH_SHORT).show() + } else if (!phone_number_input.text.all { Character.isDigit(it) }){ + Toast.makeText(this, "전화번호는 숫자로만 입력해주세요.", Toast.LENGTH_SHORT).show() + } + else{ + Toast.makeText(this, "저장이 완료되었습니다.", Toast.LENGTH_SHORT).show() + val contact: Contact = Contact( + name_input.text.toString(), + phone_number_input.text.toString(), + email_input.text.toString(), + birth_date_input.text.toString(), + gender_input.text.toString(), + memo_input.text.toString() + ) + val intent: Intent = Intent() + intent.putExtra("contactInfo", contact) + setResult(RESULT_OK, intent) + finish() + } + } + cancel_button.setOnClickListener { + Toast.makeText(this, "취소되었습니다.", Toast.LENGTH_SHORT).show() + } + } +} diff --git a/app/src/main/java/campus/tech/kakao/contacts/ContactDetailActivity.kt b/app/src/main/java/campus/tech/kakao/contacts/ContactDetailActivity.kt new file mode 100644 index 00000000..501ffcc1 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/contacts/ContactDetailActivity.kt @@ -0,0 +1,23 @@ +package campus.tech.kakao.contacts + +import android.os.Bundle +import android.widget.TextView +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat + +class ContactDetailActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_contact_detail) + + val contact = intent.getSerializableExtra("contactDetail") as Contact + + val nameTextView: TextView = findViewById(R.id.contact_name) + val phoneNumberTextView: TextView = findViewById(R.id.contact_phone_number) + + nameTextView.text = contact.name + phoneNumberTextView.text = contact.phoneNumber + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/contacts/ContactListActivity.kt b/app/src/main/java/campus/tech/kakao/contacts/ContactListActivity.kt new file mode 100644 index 00000000..9526a00d --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/contacts/ContactListActivity.kt @@ -0,0 +1,115 @@ +package campus.tech.kakao.contacts + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat.startActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import java.io.Serializable + +class ContactListActivity : AppCompatActivity() { + private lateinit var contactList: MutableList + private lateinit var adapter: ContactRecyclerAdapter + private lateinit var message: TextView + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_contact_list) + + contactList = mutableListOf() + + val contactRecyclerView: RecyclerView = findViewById(R.id.contact_list_recyclerview) + message = findViewById(R.id.add_message) + + adapter = ContactRecyclerAdapter( + contactList = contactList, + inflater = LayoutInflater.from(this@ContactListActivity), + activity = this@ContactListActivity + ) + contactRecyclerView.layoutManager = LinearLayoutManager(this@ContactListActivity) + contactRecyclerView.adapter = adapter + + val addButton: ImageView = findViewById(R.id.add_button) + addButton.setOnClickListener{ + val intent: Intent = Intent(this@ContactListActivity, ContactAddActivity::class.java) + startActivityForResult(intent, 1) + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + when(requestCode){ + 1 -> { + when(resultCode){ + AppCompatActivity.RESULT_OK -> { + val contact: Contact? = data?.getSerializableExtra("contactInfo") as Contact? + contact?.let { + contactList.add(it) + adapter.notifyItemInserted(contactList.size-1) + } + message.visibility=View.GONE + } + } + } + } + super.onActivityResult(requestCode, resultCode, data) + } +} + +class Contact( + val name: String, + val phoneNumber: String, + val email: String?, + birthDate: String?, + gender: String?, + memo: String? +) : Serializable + +class ContactRecyclerAdapter( + private val contactList: MutableList, + private val inflater: LayoutInflater, + private val activity: ContactListActivity +) : RecyclerView.Adapter() { + + inner class ViewHolder(val itemView: View) : RecyclerView.ViewHolder(itemView) { + val nameInitialTextView: TextView + val nameTextView: TextView + init { + nameInitialTextView = itemView.findViewById(R.id.name_initial_text) + nameTextView = itemView.findViewById(R.id.name_text) + + itemView.setOnClickListener { + val position = adapterPosition + if (position != RecyclerView.NO_POSITION) { + val contact = contactList[position] + val intent = Intent(activity, ContactDetailActivity::class.java) + intent.putExtra("contactDetail", contact) + activity.startActivity(intent) + } + } + } + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return ViewHolder(inflater.inflate(R.layout.item_contact, parent, false)) + } + + override fun getItemCount(): Int { + return contactList.size + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val contact = contactList.get(position) + (holder as ViewHolder).nameInitialTextView.text = contact.name.substring(0 until 1) + (holder as ViewHolder).nameTextView.text = contact.name + } + +} + + diff --git a/app/src/main/java/campus/tech/kakao/contacts/MainActivity.kt b/app/src/main/java/campus/tech/kakao/contacts/MainActivity.kt deleted file mode 100644 index 7aae79fe..00000000 --- a/app/src/main/java/campus/tech/kakao/contacts/MainActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package campus.tech.kakao.contacts - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} diff --git a/app/src/main/res/drawable/add_icon.png b/app/src/main/res/drawable/add_icon.png new file mode 100644 index 00000000..8e74aced Binary files /dev/null and b/app/src/main/res/drawable/add_icon.png differ diff --git a/app/src/main/res/drawable/arrow_down.png b/app/src/main/res/drawable/arrow_down.png new file mode 100644 index 00000000..4619cb72 Binary files /dev/null and b/app/src/main/res/drawable/arrow_down.png differ diff --git a/app/src/main/res/drawable/contacts_book.png b/app/src/main/res/drawable/contacts_book.png new file mode 100644 index 00000000..0e68691d Binary files /dev/null and b/app/src/main/res/drawable/contacts_book.png differ diff --git a/app/src/main/res/layout/activity_contact_detail.xml b/app/src/main/res/layout/activity_contact_detail.xml new file mode 100644 index 00000000..0bf1d7ac --- /dev/null +++ b/app/src/main/res/layout/activity_contact_detail.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_contact_list.xml b/app/src/main/res/layout/activity_contact_list.xml new file mode 100644 index 00000000..b1f7f0a6 --- /dev/null +++ b/app/src/main/res/layout/activity_contact_list.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 24d17df2..3ede651d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,19 +1,132 @@ - - - - - + tools:context=".ContactAddActivity" + android:orientation="vertical" + android:gravity="center_horizontal" + android:layout_weight="1" + android:background="@color/white"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +