18조 팀프로젝트 주소 : https://github.com/Team18Contact/ContactApp
김소현 님 : TabLayout X ViewPager2
전지성 님 : 연락처 추가 Dialog
김민우 님 : 연락처 리스트
이상훈 님 : 로그인 / 회원가입
package com.example.contactapp.contact
object Constants{
const val ITEM_INDEX = "item_index"
const val ITEM_OBJECT = "item_object"
}
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
}
}
}
package com.example.contactapp.contact
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
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)
}
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
gridViewContact.adapter = gridViewAdapter
recyclerViewAdapter.itemClick = object : ContactRecyclerViewAdapter.ItemClick {
override fun onClick(view: View, position: Int) {
bundleToDetailFragment(dataList[position])
}
}
gridViewAdapter.onItemClickListener = object: ContactGridViewAdapter.OnItemClickListener {
override fun onItemClick(contact: ContactModel) {
bundleToDetailFragment(contact)
}
}
}
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() = with(binding) {
recyclerViewContact.visibility = View.VISIBLE
gridViewContact.visibility = View.GONE
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null //구글 권장 메모리 누수 방지
}
}
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", "투시"))
}
}
}
package com.example.contactapp.contact
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
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.itemView.layoutDirection = View.LAYOUT_DIRECTION_LTR
} else {
holder.itemView.layoutDirection = View.LAYOUT_DIRECTION_RTL
}
}
override fun getItemCount(): Int = contactList.size
inner class Holder(private val binding: ContactRecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(contact: ContactModel) = with(binding) {
itemView.setOnClickListener {
itemClick?.onClick(it, adapterPosition)
}
imgProfile.setImageResource(contact.profile)
txtInfo.text = "${contact.name} (${contact.locale}) - ${contact.ability}"
}
}
}
package com.example.contactapp.detail
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
}
fun setData(contact: ContactModel) {
receiveData = contact
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null //구글 권장 메모리 누수 방지
}
}
package com.example.contactapp.main
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
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)
initView()
}
private fun initView() = with(binding) {
val checkName = intent.getStringExtra("userName") ?: "name"
val checkTel = intent.getStringExtra("userTel") ?: "tel"
val checkPosition = intent.getStringExtra("userPosition") ?: "position"
val checkImage = intent.getIntExtra("userImage", 0)
val detailFragment = viewPager2Adapter.getFragment(1) as? DetailFragment
detailFragment?.setData(ContactModel(R.drawable.img_kds, checkName, checkTel, "01012345678", "asd@naver.com", checkPosition))
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()
}
btnFab.setOnClickListener { //fab 클릭 리스너
//add contact dialog
}
}
}
package com.example.contactapp.main
import androidx.fragment.app.Fragment
data class MainTabs(
val fragment: Fragment,
val title: Int
)
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
}
}
package com.example.contactapp.signIn
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
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: Button
private lateinit var buttonSignUp: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
editTextEmailAddress = findViewById(R.id.editTextEmailAddress)
editTextPassword = findViewById(R.id.editTextPassword)
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 checkAbility = intent.getStringExtra("userAbility") ?: "ability"
val checkLocale = intent.getStringExtra("userLocale") ?: "locale"
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))
}
}
}
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.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_tel = findViewById<EditText>(R.id.et_tel)
val btn_signUp = findViewById<Button>(R.id.btn_signupOk)
val btn_signCancel = findViewById<Button>(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 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("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()
}
}
}
<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" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_signupOk"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="290dp"
android:layout_marginEnd="24dp"
android:backgroundTint="#FED36A"
android:radius="0dp"
android:text="@string/button_done2"
android:textColor="#000000"
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_pw" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_signupcancel"
android:layout_width="356dp"
android:layout_height="40dp"
android:layout_marginTop="6dp"
android:background="@drawable/button_background2_rect"
android:radius="0dp"
android:text="Already have an account? Log In"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/btn_signupOk"
app:layout_constraintHorizontal_bias="0.153"
app:layout_constraintStart_toStartOf="@+id/btn_signupOk"
app:layout_constraintTop_toBottomOf="@+id/btn_signupOk" />
</androidx.constraintlayout.widget.ConstraintLayout>
# activity_sign_in.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginTop="-90dp"
android:gravity="center"
android:text="@string/noticeTeam"
android:textColor="#FFFFFF"
android:textSize="45sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="8dp"
android:layout_marginTop="18dp"
android:text="@string/emailaddress"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/editTextEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="#455A64"
android:hint="@string/emailaddress"
android:inputType="text"
android:padding="16dp"
android:textColor="#FFFFFF" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:text="@string/password"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/editTextPassword"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginBottom="32dp"
android:background="#455A64"
android:hint="@string/password"
android:inputType="textPassword"
android:padding="16dp"
android:textColor="#FFFFFF" />
<Button
android:id="@+id/buttonLogin"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="16dp"
android:backgroundTint="#FED36A"
android:radius="0dp"
android:text="@string/logIn"
android:textColor="#000000" />
<Button
android:id="@+id/buttonSignUp"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="16dp"
android:background="@drawable/button_background2_rect"
android:radius="0dp"
android:text="@string/signUp"
android:textColor="#000000" />
# 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" />
<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:background="@drawable/border_item"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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>