20230908_TIL

이상훈·2023년 9월 7일

TIL

목록 보기
37/83

18조 팀프로젝트 주소 : https://github.com/Team18Contact/ContactApp

김소현 님 : TabLayout X ViewPager2

전지성 님 : 연락처 추가 Dialog

김민우 님 : 연락처 리스트

이상훈 : 로그인 / 회원가입

build.gradle

plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
}

android {
namespace 'com.example.contactapp'
compileSdk 33

defaultConfig {
    applicationId "com.example.contactapp"
    minSdk 24
    targetSdk 33
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

viewBinding {
    enabled = true
}

buildFeatures {
    viewBinding = true
}

}

dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.google.android.engage:engage-core:1.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'de.hdodenhof:circleimageview:3.1.0' // 원형 이미지뷰 만들기
}

AndroidManifest.xml

<uses-feature
    android:name="android.hardware.telephony"
    android:required="false" />

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />

<application
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.ContactApp"
    tools:targetApi="31">
    <activity
        android:name=".main.MainActivity"
        android:exported="true"/>
    <activity
        android:name=".signUp.SignUpActivity"
        android:exported="true" />
    <activity
        android:name=".signIn.SignInActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Constants.kt

package com.example.contactapp.contact

object Constants{
const val ITEM_INDEX = "item_index"
const val ITEM_OBJECT = "item_object"
}

ContactGridViewAdapter.kt

package com.example.contactapp.contact

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.BaseAdapter
import com.example.contactapp.databinding.ContactGridviewItemBinding

class ContactGridViewAdapter(private val contactList: MutableList): BaseAdapter() {
private lateinit var binding: ContactGridviewItemBinding

interface OnItemClickListener {
    fun onItemClick(contact: ContactModel)
}

var onItemClickListener: OnItemClickListener? = null

override fun getCount(): Int = contactList.size

override fun getItem(position: Int): ContactModel  = contactList[position]

override fun getItemId(position: Int): Long = position.toLong()

override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
    val holder: ViewHolder
    if (convertView == null) {
        binding = ContactGridviewItemBinding.inflate(LayoutInflater.from(parent?.context), parent, false)
        holder = ViewHolder(binding)
        binding.root.tag = holder

        binding.root.setOnClickListener {
            onItemClickListener?.onItemClick(getItem(position))
        }
    } else {
        holder = convertView.tag as ViewHolder
    }

    holder.bind(getItem(position))
    return binding.root
}

private class ViewHolder(private val binding: ContactGridviewItemBinding) {
    fun bind(contact: ContactModel) = with(binding) {
        imgProfile.setImageResource(contact.profile)
        txtName.text = contact.name
        txtAbility.text = contact.ability
    }
}

}

ContactListFragment.kt

package com.example.contactapp.contact

import android.os.Bundle
import android.provider.ContactsContract
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.example.contactapp.R
import com.example.contactapp.contact.Constants.ITEM_OBJECT
import com.example.contactapp.contact.ContactModelDB.dataList
import com.example.contactapp.databinding.FragmentContactListBinding
import com.example.contactapp.detail.DetailFragment

class ContactListFragment : Fragment() {
private var _binding: FragmentContactListBinding? = null
private val binding get() = _binding!!

private val recyclerViewAdapter by lazy {
    ContactRecyclerViewAdapter(dataList)
}

private val gridViewAdapter by lazy {
    ContactGridViewAdapter(dataList)
}

private val contactRealList by lazy {
    getContacts()
}

private val recyclerViewRealAdapter by lazy {
    ContactRecyclerViewAdapter(contactRealList)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
    _binding = FragmentContactListBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    initView()
}

private fun initView() = with(binding) {
    recyclerViewContact.adapter = recyclerViewAdapter
    val itemHelperCallback = ContactListItemHelper(requireContext(), this@ContactListFragment)
    val itemTouchHelper = ItemTouchHelper(itemHelperCallback)
    itemTouchHelper.attachToRecyclerView(recyclerViewContact)

    recyclerViewAdapter.itemClick = object : ContactRecyclerViewAdapter.ItemClick {
        override fun onClick(view: View, position: Int) {
            bundleToDetailFragment(dataList[position])
        }
    }

    recyclerViewRealAdapter.itemClick = object : ContactRecyclerViewAdapter.ItemClick {
        override fun onClick(view: View, position: Int) {
            bundleToDetailFragment(contactRealList[position])
        }
    }

    gridViewAdapter.onItemClickListener = object: ContactGridViewAdapter.OnItemClickListener {
        override fun onItemClick(contact: ContactModel) {
            bundleToDetailFragment(contact)
        }
    }
}

fun updateSwipeItem(viewHolder: RecyclerView.ViewHolder) {

// recyclerViewAdapter.notifyItemChanged(viewHolder.adapterPosition)
recyclerViewAdapter.notifyDataSetChanged()
}

fun bundleToDetailFragment(contact: ContactModel) {
    val detailFragment = DetailFragment()
    val bundle = bundleOf(ITEM_OBJECT to contact)

    detailFragment.arguments = bundle

// detailFragment.arguments = Bundle().apply {
// bundleOf(ITEM_OBJECT to dataList[position])
// }
requireActivity().supportFragmentManager.beginTransaction()
.add(R.id.mainConstrainLayout, detailFragment)
.addToBackStack(null)
.commit()
}

fun showGridView() = with(binding) {
    gridViewContact.adapter = gridViewAdapter
    recyclerViewContact.visibility = View.GONE
    gridViewContact.visibility = View.VISIBLE
}

fun showRecyclerView(num: Int) = with(binding) {
    when(num) {
        0 -> recyclerViewContact.adapter = recyclerViewAdapter
        1 -> recyclerViewContact.adapter = recyclerViewRealAdapter
    }
    recyclerViewContact.visibility = View.VISIBLE
    gridViewContact.visibility = View.GONE
}

private fun getContacts(): MutableList<ContactModel> {
    val contactList = mutableListOf<ContactModel>()
    val cursor = requireContext().contentResolver.query(
        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
        arrayOf<String>(
            ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Phone.NUMBER
        ),
        null,
        null,
        null
    )
    if(cursor != null) {

// var count = 0
// while(cursor.moveToNext() && count < 15) {
// count++ //임의로 15개까지만 출력
while(cursor.moveToNext()) {
contactList.add(ContactModel(R.drawable.ic_empty_user, cursor.getString(1), "", cursor.getString(2), "", ""))
}
}
return contactList
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null //구글 권장 메모리 누수 방지
}
}

ContactListItemHelper.kt

package com.example.contactapp.contact

import android.content.Context
import android.content.Intent
import android.graphics.Canvas
import android.net.Uri
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView

class ContactListItemHelper(private val context: Context, private val fragment: ContactListFragment): ItemTouchHelper.Callback() {
override fun isItemViewSwipeEnabled(): Boolean {
return true
}

override fun isLongPressDragEnabled(): Boolean {
    return false
}

override fun onChildDraw(
    canvas: Canvas, recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean
) {
    if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
        val view = (viewHolder as ContactRecyclerViewAdapter.Holder).linearLayout
        getDefaultUIUtil().onDraw(canvas, recyclerView, view, dX, dY, actionState, isCurrentlyActive)
    }
}

override fun clearView(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
) {
    super.clearView(recyclerView, viewHolder)
    getDefaultUIUtil().clearView((viewHolder as ContactRecyclerViewAdapter.Holder).linearLayout)
}

override fun getMovementFlags(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
): Int {
    return makeMovementFlags(0, ItemTouchHelper.RIGHT)
}

override fun onMove(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    target: RecyclerView.ViewHolder
): Boolean = false

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    val contactViewHolder = viewHolder as ContactRecyclerViewAdapter.Holder
    val phoneNumber = contactViewHolder.contactNumber

    if(direction == ItemTouchHelper.RIGHT) {
        val callUriSwipedPerson = Uri.parse("tel:${phoneNumber}")
        context.startActivity(Intent(Intent.ACTION_CALL, callUriSwipedPerson))
        fragment.updateSwipeItem(contactViewHolder)
    }
}

}

ContactModel.kt

package com.example.contactapp.contact

import android.os.Parcelable
import com.example.contactapp.R
import kotlinx.parcelize.Parcelize

@Parcelize
data class ContactModel(
val profile: Int,
val name: String,
val locale: String,
val phoneNum: String,
val email: String,
val ability: String,
) : Parcelable

object ContactModelDB {
var dataList = mutableListOf()
init {
dataList.apply{
add(ContactModel(R.drawable.img_kds, "김두식", "문산", "010-1111-1111", "kds@gmail.com", "비행"))
add(ContactModel(R.drawable.img_jjw, "장주원", "구룡포", "010-2222-2222", "jjw@gmail.com", "무한 재생"))
add(ContactModel(R.drawable.img_lmh, "이미현", "비공개", "010-3333-3333", "lmh@gmail.com", "초인적 오감"))
add(ContactModel(R.drawable.img_jgd, "전계도", "비공개", "010-4444-4444", "jgd@gmail.com", "전기"))
add(ContactModel(R.drawable.img_frank, "프랭크", "아이오와", "010-5555-5555", "frank@gmail.com", "무한재생"))
add(ContactModel(R.drawable.img_ljm, "이재만", "비공개", "010-6666-6666", "ljm@gmail.com", "괴력, 스피드"))
add(ContactModel(R.drawable.img_jsj, "정상진", "진천", "010-7777-7777", "jsj@gmail.com", "괴력"))
add(ContactModel(R.drawable.img_jys, "전영석", "봉평", "010-8888-8888", "jys@gmail.com", "전기"))
add(ContactModel(R.drawable.img_hsh, "홍성화", "나주", "010-9999-9999", "hsh@gmail.com", "투시"))
}
}
}

ContactRecyclerViewAdapter.kt

package com.example.contactapp.contact

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.example.contactapp.databinding.ContactRecyclerviewItemBinding

class ContactRecyclerViewAdapter (private val contactList: MutableList) : RecyclerView.Adapter<ContactRecyclerViewAdapter.Holder>(){
interface ItemClick {
fun onClick(view : View, position : Int)
}

var itemClick : ItemClick? = null

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {//
    val binding = ContactRecyclerviewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    return Holder(binding) // holder return
}

override fun onBindViewHolder(holder: Holder, position: Int) {
    holder.bind(contactList[position])

    if(position % 2 == 0) {
        holder.linearLayout.layoutDirection = View.LAYOUT_DIRECTION_LTR
    } else {
        holder.linearLayout.layoutDirection = View.LAYOUT_DIRECTION_RTL
    }
}

override fun getItemCount(): Int = contactList.size

inner class Holder(private val binding: ContactRecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
    lateinit var linearLayout: LinearLayout
    lateinit var contactNumber: String
    fun bind(contact: ContactModel) = with(binding) {
        linearLayout = contactLinearLayout
        contactNumber = contact.phoneNum

        itemView.setOnClickListener {
            itemClick?.onClick(it, adapterPosition)
        }

        imgProfile.setImageResource(contact.profile)
        val localeTxt = if(contact.locale.isNotEmpty()) " (${contact.locale}) " else contact.locale
        val abilityTxt = if(contact.ability.isNotEmpty()) "- ${contact.ability}" else contact.ability
        txtInfo.text = "${contact.name}$localeTxt$abilityTxt"
    }
}

}

DetailFragment.kt

package com.example.contactapp.detail

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.res.ResourcesCompat
import com.example.contactapp.contact.Constants
import com.example.contactapp.contact.Constants.ITEM_OBJECT
import com.example.contactapp.contact.ContactModel
import com.example.contactapp.contact.ContactModelDB
import com.example.contactapp.databinding.FragmentDetailBinding

class DetailFragment : Fragment() {
private var _binding: FragmentDetailBinding? = null
private val binding get() = _binding!!

private val data: ContactModel? by lazy {
    arguments?.getParcelable<ContactModel>(ITEM_OBJECT)
}
lateinit var receiveData: ContactModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
    _binding = FragmentDetailBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    initView()
}

private fun initView() = with(binding) {
    val receiveData = data ?: receiveData
    imgPhoto.setImageDrawable(receiveData?.let {
        ResourcesCompat.getDrawable(
            resources,
            it.profile,
            null
        )
    })
    tvName.text = receiveData?.name
    tvPhoneNumber.text = receiveData?.phoneNum
    tvEmail.text = receiveData?.email
    tvLocale.text = receiveData?.locale
    tvAbility.text = receiveData?.ability

    /**
     *  data 값이 null이면 receiveData를 받아오니까, 이 경우가 마이페이지 데이터가 보이는 경우이므로
     *  메세지, 콜 버튼을 사라지게 했습니다!
     */
    if (data == null) {
        btnMessageButton.visibility = View.GONE
        btnCallButton.visibility = View.GONE
    } // 마이페이지 일 때, 메세지 및 콜 버튼 사라지는 기능 완료

    /**
     *  디테일 페이지에서 버튼을 누르면 전화와 문자를 보내는 기능 추가입니다.
     */
    btnCallButton.setOnClickListener {
        val phoneNumber = tvPhoneNumber.text
        val callUriSwipedPerson = Uri.parse("tel:${phoneNumber}")
        startActivity(Intent(Intent.ACTION_CALL, callUriSwipedPerson))
    }

    btnMessageButton.setOnClickListener {
        val phoneNumber = tvPhoneNumber.text
        val sendUriSwipedPerson = Uri.parse("smsto:${phoneNumber}")
        startActivity(Intent(Intent.ACTION_SENDTO, sendUriSwipedPerson))
    } // 디테일 페이지 버튼 기능 완료


}

fun setData(contact: ContactModel) {
    receiveData = contact
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null //구글 권장 메모리 누수 방지
}

}

MainActivity.kt

package com.example.contactapp.main

import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.viewpager2.widget.ViewPager2
import com.example.contactapp.R
import com.example.contactapp.contact.ContactListFragment
import com.example.contactapp.contact.ContactModel
import com.example.contactapp.databinding.ActivityMainBinding
import com.example.contactapp.detail.DetailFragment
import com.google.android.material.tabs.TabLayoutMediator

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewPager2Adapter by lazy {
MainViewPagerAdapter(this@MainActivity)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    checkPermission()
}

private fun initView() = with(binding) {
    val checkName = intent.getStringExtra("userName") ?: "name"
    val checkEmailAddress = intent.getStringExtra("userEmailAddress") ?: "emailaddress"
    val checkTel = intent.getStringExtra("userTel") ?: "tel"
    val checkLocale = intent.getStringExtra("userLocale") ?: "locale"
    val checkAbility = intent.getStringExtra("userAbility") ?: "ability"

    val detailFragment = viewPager2Adapter.getFragment(1) as? DetailFragment
    detailFragment?.setData(ContactModel(R.drawable.ic_empty_user, checkName, checkLocale, checkTel, checkEmailAddress, checkAbility))

    viewPager2.adapter = viewPager2Adapter

    viewPager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
        override fun onPageSelected(position: Int) {
            super.onPageSelected(position)
            if(viewPager2Adapter.getFragment(position) is ContactListFragment) {
                imgGridView.visibility = View.VISIBLE
                imgListView.visibility = View.VISIBLE
            } else {
                imgGridView.visibility = View.INVISIBLE
                imgListView.visibility = View.INVISIBLE
            }
        }
    })

    TabLayoutMediator(tabLayout, viewPager2) { tab, pos ->
        tab.setText(viewPager2Adapter.getTitle(pos))
    }.attach()

    val contactListFragment = viewPager2Adapter.getFragment(0) as? ContactListFragment
    imgGridView.setOnClickListener {
        contactListFragment?.showGridView()
    }

    imgListView.setOnClickListener {
        contactListFragment?.showRecyclerView(0)
    }

    imgListView.setOnLongClickListener {
        contactListFragment?.showRecyclerView(1)
        true
    }

    btnFab.setOnClickListener { //fab 클릭 리스너
        //add contact dialog
    }
}

private fun checkPermission() {
    if(ContextCompat.checkSelfPermission(this, "android.permission.READ_CONTACTS") != PackageManager.PERMISSION_GRANTED
        || ContextCompat.checkSelfPermission(this, "android.permission.CALL_PHONE") != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.READ_CONTACTS", "android.permission.CALL_PHONE"), 100)
    } else {
        initView()
    }
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED
        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "PERMISSION GRANTED", Toast.LENGTH_SHORT).show()
        initView()
    } else {
        Toast.makeText(this, "PERMISSION DENIED", Toast.LENGTH_SHORT).show()
        finish()
    }
}

}

MainTabs.kt

package com.example.contactapp.main

import androidx.fragment.app.Fragment

data class MainTabs(
val fragment: Fragment,
val title: Int
)

MainViewPagerAdapter.kt

package com.example.contactapp.main

import android.content.Context
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.example.contactapp.R
import com.example.contactapp.contact.ContactListFragment
import com.example.contactapp.databinding.ActivityMainBinding
import com.example.contactapp.detail.DetailFragment

class MainViewPagerAdapter(fragmentActivity: FragmentActivity): FragmentStateAdapter(fragmentActivity) {
private var fragments: ArrayList = ArrayList()

init {
    fragments.add(MainTabs(ContactListFragment(), R.string.main_tab_title_contact))
    fragments.add(MainTabs(DetailFragment(), R.string.main_tab_title_mypage))
}

fun getFragment(position: Int): Fragment {
    return fragments[position].fragment
}

fun getTitle(position: Int): Int {
    return fragments[position].title
}

override fun getItemCount(): Int = fragments.size

override fun createFragment(position: Int): Fragment {



    return fragments[position].fragment
}

}

SignInActivity.kt

package com.example.contactapp.signIn

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.contactapp.R
import com.example.contactapp.main.MainActivity
import com.example.contactapp.signUp.SignUpActivity

class SignInActivity : AppCompatActivity() {

private lateinit var editTextEmailAddress: EditText
private lateinit var editTextPassword: EditText
private lateinit var buttonLogin: TextView
private lateinit var buttonSignUp: TextView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_sign_in)

    editTextEmailAddress = findViewById(R.id.et_login_id)
    editTextPassword = findViewById(R.id.et_login_password)
    buttonLogin = findViewById(R.id.buttonLogin)
    buttonSignUp = findViewById(R.id.buttonSignUp)

    buttonLogin.setOnClickListener {

        val emailaddress = editTextEmailAddress.text.toString()
        val password = editTextPassword.text.toString()

        val checkName = intent.getStringExtra("userName") ?: "name"
        val checkEmailAddress = intent.getStringExtra("userEmailAddress") ?: "emailaddress"
        val checkPw = intent.getStringExtra("userPw") ?: "pw"
        val checkTel = intent.getStringExtra("userTel") ?: "tel"
        val checkLocale = intent.getStringExtra("userLocale") ?: "locale"
        val checkAbility = intent.getStringExtra("userAbility") ?: "ability"
        val checkImage = intent.getIntExtra("userImage", 0)


        if (emailaddress.isEmpty() || password.isEmpty()) {


            Toast.makeText(this, "아이디/비밀번호 둘 중 하나가 입력이 비어있습니다.", Toast.LENGTH_SHORT).show()
        } else if((emailaddress.equals(checkEmailAddress)) && (password.equals(checkPw))){

            Toast.makeText(this, R.string.successLogin, Toast.LENGTH_SHORT).show()


            val intent = Intent(this, MainActivity::class.java)

            intent.putExtra("userName", checkName)
            intent.putExtra("userEmailAddress", checkEmailAddress)
            intent.putExtra("userPw", checkPw)
            intent.putExtra("userTel", checkTel)
            intent.putExtra("userAbility", checkAbility)
            intent.putExtra("userLocale", checkLocale)
            intent.putExtra("userImage", checkImage)
            startActivity(intent)
            finish()
        }
        else{
            Toast.makeText(this, R.string.checkIDPassword, Toast.LENGTH_SHORT).show()
        }
    }

    buttonSignUp.setOnClickListener {
        startActivity(Intent(this, SignUpActivity::class.java))
    }
}

}

SignUpActivity.kt

package com.example.contactapp.signUp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import com.example.contactapp.R
import com.example.contactapp.signIn.SignInActivity
import java.util.regex.Pattern

class SignUpActivity : AppCompatActivity() {

private val emailaddressPattern = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)\$")
private val pwPattern = Pattern.compile("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#\$%^&+=]).{8,15}\$")
private val localePattern = Pattern.compile("^[가-힣a-zA-Z]*\$")
private val namePattern = Pattern.compile("^[가-힣a-zA-Z]*\$")
private val telPattern = Pattern.compile("^[0-9]{10,11}\$")
private var imgSet: Int = R.drawable.logo1 // 기본 값으로 초기화

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_sign_up)

    val et_name = findViewById<EditText>(R.id.et_name)
    val et_emailaddress = findViewById<EditText>(R.id.et_emailaddress)
    val et_pw = findViewById<EditText>(R.id.et_pw)
    val et_locale = findViewById<EditText>(R.id.et_locale)
    val et_ability = findViewById<EditText>(R.id.et_ability)
    val et_tel = findViewById<EditText>(R.id.et_tel)
    val btn_signUp = findViewById<TextView>(R.id.btn_signupOk)
    val btn_signCancel = findViewById<TextView>(R.id.btn_signupcancel)




    et_emailaddress.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val emailaddress = s.toString()
            val valid = emailaddressPattern.matcher(emailaddress).matches()
            if (!valid) {
                et_emailaddress.error = getString(R.string._5_10)
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

    et_pw.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val pw = s.toString()
            val valid = pwPattern.matcher(pw).matches()
            if (!valid) {
                et_pw.error = getString(R.string._8_15)
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

    et_locale.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val locale = s.toString()
            val valid = localePattern.matcher(locale).matches()
            if (!valid) {
                et_locale.error = getString(R.string.kor)
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

    et_tel.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val tel = s.toString()
            val valid = telPattern.matcher(tel).matches()
            if (!valid) {
                et_tel.error = getString(R.string._10_11)
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

    et_name.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val name = s.toString()
            val valid = namePattern.matcher(name).matches()
            if (!valid) {
                et_name.error = getString(R.string.kor)
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

    //이미지 초기화

// val iv_logo = findViewById(R.id.imageView)
// iv_logo.setOnClickListener {
// imgSet = when ((1..6).random()) {
// 1 -> R.drawable.logo1
// 2 -> R.drawable.logo2
// 3 -> R.drawable.logo3
// 4 -> R.drawable.logo4
// 5 -> R.drawable.logo5
// else -> R.drawable.logo1
// }
//
// iv_logo.setImageDrawable(ResourcesCompat.getDrawable(resources, imgSet, null))
//
// }

    btn_signUp.setOnClickListener{
        val name = et_name.text.toString()
        val emailaddress = et_emailaddress.text.toString()
        val pw = et_pw.text.toString()
        val locale = et_locale.text.toString()
        val ability = et_ability.text.toString()
        val tel = et_tel.text.toString()

        if (name.isBlank() || emailaddress.isBlank() || pw.isBlank() || locale.isBlank() || tel.isBlank()) {
            Toast.makeText(this, getString(R.string.info), Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }


        val nameValid = namePattern.matcher(name).matches()
        val emailaddressValid = emailaddressPattern.matcher(emailaddress).matches()
        val pwValid = pwPattern.matcher(pw).matches()
        val localeValid = localePattern.matcher(locale).matches()
        val telValid = telPattern.matcher(tel).matches()

        if (!nameValid) {
            et_name.error = getString(R.string.kor)
            return@setOnClickListener
        }

        if (!emailaddressValid) {
            et_emailaddress.error = getString(R.string._5_10)
            return@setOnClickListener
        }

        if (!pwValid) {
            et_pw.error = getString(R.string._8_15)
            return@setOnClickListener
        }

        if (!localeValid) {
            et_locale.error = getString(R.string.kor)
            return@setOnClickListener
        }

        if (!telValid) {
            et_tel.error = getString(R.string._10_11)
            return@setOnClickListener
        }

        val intent = Intent(this, SignInActivity::class.java)

        //수정하겠습니다.
        intent.putExtra("userName", name)
        intent.putExtra("userEmailAddress", emailaddress)
        intent.putExtra("userPw", pw)
        intent.putExtra("userTel", tel)
        intent.putExtra("userLocale", locale)
        intent.putExtra("userAbility", ability)
        intent.putExtra("userImage",imgSet)

        startActivity(intent)
        finish()
    }

    btn_signCancel.setOnClickListener {
        Toast.makeText(this@SignUpActivity, "취소 되었습니다.", Toast.LENGTH_SHORT).show()
        val intent = Intent(this@SignUpActivity, SignInActivity::class.java)
        startActivity(intent)
        finish()
    }


}

}

colors.xml

#FF000000 #FFFFFFFF #D9D9D9 #D9D9D9 #3A75F4 #FFFED36A #FAEAC4 #FF455A64 #FF20222C #1F63AA

strings.xml

ContactApp
<string name="main_fab_btn_description">FabBtn to add contact</string>
<string name="main_tab_title_contact">CONTACT</string>
<string name="main_tab_title_mypage">MY PAGE</string>
<string name="main_toolbar_title">무빙 출연진 연락처</string>

<string name="mypage_todo_edittext_hint">할일 추가하기</string>
<string name="mypage_todo_textview_title">할일 목록</string>
<string name="button_done">Log In</string>
<string name="button_done2">SIGN UP</string>
<string name="butotn_input">입력</string>
<string name="mypage_overlap_todo">이미 등록된 할일이 목록에 존재합니다.</string>
<string name="mypage_edittext_null">할일을 추가하시려면 텍스트를 입력해주세요!</string>

<string name="intent_userImage">userImage</string>
<string name="intent_userNameText">userName</string>
<string name="intent_userPositionText">userPosition</string>
<string name="intent_userTelText">userTel</string>


<string name="_5_10">5~10자의 영어(대소문자)와 숫자만 입력하세요.</string>
<string name="_8_15">8~15자의 영어(대소문자), 숫자, 특수문자를 포함하세요.</string>
<string name="_10_11">10~11자의 숫자만 입력하세요.</string>
<string name="kor">한글 또는 영어만 입력하세요.</string>
<string name="info">입력되지 않은 정보가 있습니다</string>

<string name="signup_cancel1">취소 되었습니다.</string>

//detail
<string name="warningBack">작성 중인 내용이 삭제될 수도 있습니다.</string>
<string name="warningNull">입력된 값이 없습니다.</string>
<string name="noticeComment">댓글을 입력하세요.</string>
<string name="comment">댓글</string>

//signIn
<string name="noticeTeam">Welcome Back!</string>
<string name="emailaddress">Email Address</string>
<string name="password">Password</string>
<string name="tel">TelPhone</string>
<string name="logIn">LOGIN</string>
<string name="signUp">SIGN UP</string>
<string name="checkIDPassword">아이디/비밀번호를 확인해주세요</string>
<string name="successLogin">로그인 성공</string>

//writePage
<string name="subject">제목</string>
<string name="inputContents">내용을 입력해주세요</string>
<string name="cancel">취소</string>

//main
<string name="name">Full name</string>
<string name="nameColon">이름 : </string>
<string name="position">Ability</string>
<string name="positionColon">직책 : </string>
<string name="teamMember">팀 멤버</string>
<string name="teamNoticeBoard">팀 게시판</string>

//signUp
<string name="notice2Team">SIGN UP</string>
<string name="inputID">이메일을 입력하세요.</string>
<string name="inputPassword">비밀번호를 입력하세요.</string>
<string name="inputPosition">(입력 안해도 됨)</string>
<string name="inputTel">전화번호를 입력하세요.</string>
<string name="locale">Locale</string>
<string name="inputLocale">지역명</string>

themes.xml

<style name="Theme.ContactApp" parent="Base.Theme.ContactApp" />

<style name="btnFab">
    <item name="cornerSize">50%</item>
</style>

activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainConstrainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/contact_black"
tools:context=".main.MainActivity">

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolBar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/contact_yellow"
    android:padding="16dp"
    app:layout_constraintBottom_toTopOf="@id/viewPager2"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="@string/main_toolbar_title"
        android:textColor="@color/white"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/img_listView"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_gravity="end"
        android:layout_marginEnd="16dp"
        android:src="@drawable/ic_list_view" />

    <ImageView
        android:id="@+id/img_gridView"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_gravity="end"
        android:layout_marginEnd="10dp"
        android:src="@drawable/ic_grid_view" />
</androidx.appcompat.widget.Toolbar>

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager2"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@id/tabLayout"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/toolBar" />

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/contact_yellow"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/viewPager2"
    app:tabIndicatorColor="@color/contact_darkGray"
    app:tabIndicatorFullWidth="true"
    app:tabSelectedTextColor="@color/contact_darkGray"
    app:tabTextColor="@color/black" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/btn_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:contentDescription="@string/main_fab_btn_description"
    android:src="@drawable/ic_add_contact"
    app:backgroundTint="@color/contact_yellow"
    app:layout_constraintBottom_toTopOf="@id/tabLayout"
    app:layout_constraintEnd_toEndOf="parent"
    app:shapeAppearanceOverlay="@style/btnFab" />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_sign_in.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#212832"

android:orientation="vertical"
android:padding="0dp">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">


    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"


        >

        <ImageView
            android:id="@+id/logo_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp"
            android:gravity="center"
            android:src="@drawable/login_moving_logo"

            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/txt_login_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:layout_marginHorizontal="20dp"

            android:layout_marginTop="26dp"
            android:text="@string/emailaddress"
            android:textColor="#8CAAB9"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/logo_login"

            />


        <EditText
            android:id="@+id/et_login_id"
            android:layout_width="match_parent"
            android:layout_height="55dp"

            android:layout_marginHorizontal="20dp"
            android:background="#455A64"
            android:hint="@string/emailaddress"
            android:inputType="text"
            android:padding="16dp"

            android:textColor="#FFFFFF"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt_login_id"


            />

        <TextView
            android:id="@+id/txt_login_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:layout_marginHorizontal="20dp"


            android:layout_marginTop="26dp"
            android:text="@string/password"
            android:textColor="#8CAAB9"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/et_login_id"


            />

        <EditText
            android:id="@+id/et_login_password"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginBottom="32dp"
            android:background="#455A64"
            android:hint="@string/password"
            android:inputType="textPassword"
            android:padding="16dp"
            android:textColor="#FFFFFF"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt_login_password" />

        <TextView
            android:id="@+id/buttonLogin"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="60dp"
            android:background="#FED36A"


            android:gravity="center"

            android:text="@string/logIn"
            android:textSize="20dp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/et_login_password"
            app:layout_constraintBottom_toTopOf="@id/buttonSignUp"


            />

        <TextView
            android:id="@+id/buttonSignUp"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:textSize="20dp"
            android:gravity="center"


            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:layout_marginBottom="26dp"
            android:background="@color/login_blue"
            android:textStyle="bold"

            android:text="@string/signUp"


            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"

            app:layout_constraintTop_toBottomOf="@+id/buttonLogin"


            />


    </androidx.constraintlayout.widget.ConstraintLayout>


</ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

activity_sign_up.xml

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="@string/notice2Team"
        android:textColor="#FFFFFF"
        android:textSize="35sp"
        android:textStyle="bold"
        tools:layout_editor_absoluteX="-24dp"
        tools:layout_editor_absoluteY="16dp" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="24dp"
        android:text="@string/name"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <EditText
        android:id="@+id/et_name"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:ems="10"
        android:hint="@string/name"
        android:padding="12dp"
        android:inputType="text"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_name" />

    <TextView
        android:id="@+id/tv_locale"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="24dp"
        android:text="@string/locale"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_pw" />

    <EditText
        android:id="@+id/et_locale"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:ems="10"
        android:hint="@string/inputLocale"
        android:padding="12dp"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_locale" />

    <TextView
        android:id="@+id/tv_ability"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="24dp"
        android:text="@string/position"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_locale" />

    <EditText
        android:id="@+id/et_ability"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:textColor="#FFFFFF"
        android:ems="10"
        android:textSize="18sp"
        android:hint="@string/inputPosition"
        android:padding="12dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_ability" />

    <TextView
        android:id="@+id/tv_emailaddress"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="24dp"
        android:text="@string/emailaddress"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_name" />

    <EditText
        android:id="@+id/et_emailaddress"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:textColor="#FFFFFF"
        android:ems="10"
        android:textSize="18sp"
        android:hint="@string/inputID"
        android:padding="12dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_emailaddress" />

    <TextView
        android:id="@+id/tv_pw"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="24dp"
        android:text="@string/password"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_emailaddress" />

    <EditText
        android:id="@+id/et_pw"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:textColor="#FFFFFF"
        android:ems="10"
        android:textSize="18sp"
        android:hint="@string/inputPassword"
        android:padding="12dp"
        android:inputType="textPassword"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_pw" />

    <TextView
        android:id="@+id/tv_tel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="24dp"
        android:text="@string/tel"
        android:textColor="#8CAAB9"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_ability" />

    <EditText
        android:id="@+id/et_tel"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="24dp"
        android:background="#455A64"
        android:textColor="#FFFFFF"
        android:ems="10"
        android:textSize="18sp"
        android:hint="@string/inputTel"
        android:padding="12dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_tel" />

    <TextView
        android:id="@+id/btn_signupOk"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="26dp"
        android:layout_marginEnd="24dp"
        android:gravity="center"


        android:text="@string/button_done2"
        android:background="#FED36A"

        android:textSize="20dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_tel" />

    <TextView
        android:id="@+id/btn_signupcancel"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginTop="26dp"
        android:background="@color/login_blue"

        android:text="Already have an account? LOGIN"
        android:gravity="center"
        android:textSize="20dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="@+id/btn_signupOk"

        app:layout_constraintStart_toStartOf="@+id/btn_signupOk"
        app:layout_constraintTop_toBottomOf="@+id/btn_signupOk" />

</androidx.constraintlayout.widget.ConstraintLayout>

contact_gridview_item.xml

<androidx.cardview.widget.CardView
    android:id="@+id/CardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    apps:cardCornerRadius="100dp"
    apps:cardElevation="0dp">

    <ImageView
        android:id="@+id/img_profile"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop" />
</androidx.cardview.widget.CardView>

<TextView
    android:id="@+id/txt_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="5dp"
    android:textColor="@color/white"
    android:textSize="16sp" />

<TextView
    android:id="@+id/txt_ability"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="5dp"
    android:textColor="@color/white"
    android:textSize="12sp" />

contact_recyclerview_item.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:apps="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">

<LinearLayout
    android:id="@+id/back_linearLayout"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@drawable/border_item_background_yellow"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="16dp"
    apps:layout_constraintBottom_toBottomOf="@id/contact_linearLayout"
    apps:layout_constraintEnd_toEndOf="@id/contact_linearLayout"
    apps:layout_constraintStart_toStartOf="@id/contact_linearLayout"
    apps:layout_constraintTop_toTopOf="@id/contact_linearLayout">

    <ImageView
        android:id="@+id/img_call"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_call" />

</LinearLayout>

<LinearLayout
    android:id="@+id/contact_linearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/border_item_background_black"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="16dp"
    apps:layout_constraintBottom_toBottomOf="parent"
    apps:layout_constraintEnd_toEndOf="parent"
    apps:layout_constraintStart_toStartOf="parent"
    apps:layout_constraintTop_toTopOf="parent">

    <androidx.cardview.widget.CardView
        android:id="@+id/CardView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        apps:cardCornerRadius="100dp"
        apps:cardElevation="0dp">

        <ImageView
            android:id="@+id/img_profile"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop" />

    </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/txt_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="@color/white"
        android:textSize="18sp" />

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <ImageView
        android:id="@+id/img_like"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:src="@drawable/ic_empty_heart" />
</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_contact_list.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".contact.ContactListFragment">

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView_contact"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_marginTop="8dp"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:listitem="@layout/contact_recyclerview_item" />

<GridView
    android:id="@+id/gridView_contact"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:horizontalSpacing="8dp"
    android:numColumns="3"
    android:padding="8dp"
    android:verticalSpacing="8dp"
    android:visibility="gone"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_detail.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#20222C"
tools:context="detail.DetailFragment">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintTop_toTopOf="parent"

    >

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- 디테일, 마이페이지  -->
        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/img_photo"
            android:layout_width="266dp"
            android:layout_height="266dp"
            android:layout_marginTop="50dp"
            android:src="@drawable/ic_launcher_background"

            app:civ_border_color="@color/white"
            app:civ_border_width="5dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/btn_messageButton"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:layout_marginTop="50dp"
            android:background="#FED36A"
            android:gravity="center"
            android:text="MESSAGE"
            android:textStyle="bold"
            android:visibility="visible"
            app:layout_constraintEnd_toStartOf="@id/btn_callButton"
            app:layout_constraintStart_toStartOf="@id/iv_name"
            app:layout_constraintTop_toBottomOf="@id/img_photo" />

        <TextView
            android:id="@+id/btn_callButton"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:layout_marginTop="50dp"
            android:background="#263238"
            android:gravity="center"
            android:text="CALL"
            android:textStyle="bold"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="@id/iv_name"
            app:layout_constraintStart_toEndOf="@id/btn_messageButton"
            app:layout_constraintTop_toBottomOf="@id/img_photo" />

        <!--네임 -->

        <ImageView
            android:id="@+id/iv_name"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:background="#455A64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_messageButton" />

        <ImageView
            android:id="@+id/icon_name"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="14dp"
            android:src="@drawable/detail_name"

            app:layout_constraintBottom_toBottomOf="@id/iv_name"
            app:layout_constraintStart_toStartOf="@id/iv_name"
            app:layout_constraintTop_toTopOf="@id/iv_name" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:gravity="center_vertical"
            android:text="이름"
            android:textColor="@color/white"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@id/iv_name"
            app:layout_constraintStart_toEndOf="@id/icon_name"
            app:layout_constraintTop_toTopOf="@id/iv_name" />


        <!-- 번호-->
        <ImageView
            android:id="@+id/iv_phoneNumber"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:background="#455A64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/iv_name" />

        <ImageView
            android:id="@+id/icon_phoneNumber"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="14dp"
            android:src="@drawable/detail_phone"

            app:layout_constraintBottom_toBottomOf="@id/iv_phoneNumber"
            app:layout_constraintStart_toStartOf="@id/iv_phoneNumber"
            app:layout_constraintTop_toTopOf="@id/iv_phoneNumber" />

        <TextView
            android:id="@+id/tv_phoneNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:gravity="center_vertical"
            android:text="010-0000-0000"
            android:textColor="@color/white"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@id/iv_phoneNumber"
            app:layout_constraintStart_toEndOf="@id/icon_phoneNumber"
            app:layout_constraintTop_toTopOf="@id/iv_phoneNumber" />

        <!-- 이메일-->
        <ImageView
            android:id="@+id/iv_email"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:background="#455A64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/iv_phoneNumber" />

        <ImageView
            android:id="@+id/icon_email"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="14dp"
            android:src="@drawable/detail_email"

            app:layout_constraintBottom_toBottomOf="@id/iv_email"
            app:layout_constraintStart_toStartOf="@id/iv_email"
            app:layout_constraintTop_toTopOf="@id/iv_email" />

        <TextView
            android:id="@+id/tv_email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:gravity="center_vertical"
            android:text="Test@naver.com"
            android:textColor="@color/white"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@id/iv_email"
            app:layout_constraintStart_toEndOf="@id/icon_email"
            app:layout_constraintTop_toTopOf="@id/iv_email" />

        <!-- locale-->
        <TextView
            android:id="@+id/iv_locale"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:background="#455A64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/iv_email" />

        <ImageView
            android:id="@+id/icon_locale"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="14dp"
            android:src="@drawable/detail_check"

            app:layout_constraintBottom_toBottomOf="@id/iv_locale"
            app:layout_constraintStart_toStartOf="@id/iv_locale"
            app:layout_constraintTop_toTopOf="@id/iv_locale" />

        <TextView
            android:id="@+id/tv_locale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:gravity="center_vertical"
            android:text="Locale"
            android:textColor="@color/white"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@id/iv_locale"
            app:layout_constraintStart_toEndOf="@id/icon_locale"
            app:layout_constraintTop_toTopOf="@id/iv_locale" />

        <!-- ability -->

        <TextView
            android:id="@+id/iv_ability"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginHorizontal="20dp"
            android:layout_marginTop="26dp"
            android:layout_marginBottom="60dp"
            android:background="#455A64"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/iv_locale" />

        <ImageView
            android:id="@+id/icon_ability"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="14dp"
            android:src="@drawable/detail_thunder"

            app:layout_constraintBottom_toBottomOf="@id/iv_ability"
            app:layout_constraintStart_toStartOf="@id/iv_ability"
            app:layout_constraintTop_toTopOf="@id/iv_ability" />

        <TextView
            android:id="@+id/tv_ability"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:gravity="center_vertical"
            android:text="Ability"
            android:textColor="@color/white"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@id/iv_ability"
            app:layout_constraintStart_toEndOf="@id/icon_ability"
            app:layout_constraintTop_toTopOf="@id/iv_ability" />


    </androidx.constraintlayout.widget.ConstraintLayout>


</ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

profile
열심히 하자

0개의 댓글