20230907_TIL

이상훈·2023년 9월 7일

TIL

목록 보기
36/83

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

김소현 님 : TabLayout X ViewPager2

전지성 님 : 연락처 추가 Dialog

김민우 님 : 연락처 리스트

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

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 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 //구글 권장 메모리 누수 방지
}

}

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 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}"
    }
}

}

DetailFragment.kt

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 //구글 권장 메모리 누수 방지
}

}

MainActivity.kt

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
    }
}

}

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.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))
    }
}

}

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.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()
    }


}

}

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" />

    <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" />

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: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>

profile
열심히 하자

0개의 댓글