recyclerview를 사용할때 item의 배경색을 바꿔주면 모든 값들의 배경색이 같아져서 이쁘지 않아보인다. 이때 사용할수 있다. 리사이클러뷰 배경색, 순차배경색

위와같이 만들 수 있다.
사용법 ->
리사이클러뷰 어뎁터에서 사용할 색을 전역변수로 선언해서 만들어준다.
private val alterBackColors = arrayOf(
R.color.white,
R.color.mainColor
)
그 뒤에 오버라이딩한 onBindViewHolder안에서 이렇게 사용해주면 된다.
val backgroundColor = ContextCompat.getColor(
holder.itemView.context,
alterBackColors[position % alterBackColors.size]
)
holder.itemView.setBackgroundColor(backgroundColor)
만약 두가지색상이 아닌 세가지 색상을 사용하고싶다면 그냥 배열안에 색을 추가만 해주면 된다.
dialog안에서 imageView를 만들고, 해당 이미지뷰를 클릭시 앨범으로이동, 사진을 가져와서 해당 이미지뷰에 사진을 띄울 수 있게 만들어주었다.
그래들 설정을 추가해준다. 나는 Glide를 이용해서 이미지를 받아왔다.
implementation("com.github.bumptech.glide:glide:4.12.0")
다음으로 이미지 선택에 대한 Boolean값을 선언해준다. 이유는 뒤에서 설명.
private var isImageSelected = false
다음으로 이미지를 클릭시 앨범을 불러온다.
userImg.setOnClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, DEFAULT_GALLERY_REQUEST_CODE)
}
마지막으로 onActivityResult를 오버라이딩해서 이미지를 받아온다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != Activity.RESULT_OK) return
when (requestCode) {
DEFAULT_GALLERY_REQUEST_CODE -> {
data ?: return
selectedImageUri = data.data as Uri
Glide.with(this).load(selectedImageUri).into(userImg)
isImageSelected = !isImageSelected
}
else -> {
userImg.setImageResource(R.drawable.user)
}
}
}
사진을 uri형식으로 받아오고, 추가해준 Glide라이브러리를 이용해서 사진을 띄워줬다. 아무사진도 클릭되지 않았을때는 기본 이미지를 넣어주었다. 위에서 선언해준 isImageSelected가 들어간 이유는 처음에 설명했듯이 나는 dialog를 이용해서 사진을 불러오는데, 확인버튼을 누르면 입력한 데이터가 recyclerView에 업데이트 되게 만들었다. 여기서 isImageSelected가 없다면 아무 사진을 고르지 않아도, 이전에 골랐던 uri가 그대로 남아있어서 이전에 사용했던 사진이 사용되는 오류가 있어서 넣어줬다.
플로팅 버튼을 하나 만들고, 해당버튼을 클릭했을때 Dialog화면을 하나 띄워서 정보를 작성하고, 데이터를 추가할 수 있게 만들 수 있다.

다이얼로그는 custom Dialog를 사용해서 내가 원하는 값들을 넣어줬다.
with(binding) {
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
floatingBtn.setOnClickListener {
val builder = AlertDialog.Builder(requireContext())
builder.setTitle("커스텀 다이얼로그")
builder.setIcon(R.mipmap.ic_launcher)
val v1 = layoutInflater.inflate(R.layout.add_user_dialog, null)
builder.setView(v1)
userImg = v1.findViewById(R.id.addUserImg)
val nameEdit = v1.findViewById<EditText>(R.id.addUserName)
val phoneEdit = v1.findViewById<EditText>(R.id.addUserPhone)
val statusEdit = v1.findViewById<EditText>(R.id.addUserStatus)
val emailEdit = v1.findViewById<EditText>(R.id.addUserEmail)
userImg.setOnClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, DEFAULT_GALLERY_REQUEST_CODE)
}
val listener = DialogInterface.OnClickListener { p0, p1 ->
val name = nameEdit.text.toString()
val phone = phoneEdit.text.toString()
val state = statusEdit.text.toString()
val email = emailEdit.text.toString()
val newItem: MyItem
if(isImageSelected){
newItem = MyItem(
selectedImageUri,
name,
R.drawable.ic_star_blank,
email,
state,
phone
)
isImageSelected = !isImageSelected
} else{
newItem = MyItem(
Uri.parse("android.resource://com.example.anycall/drawable/user"),
name,
R.drawable.ic_star_blank,
email,
state,
phone
)
}
dataList.add(newItem)
adapter.notifyDataSetChanged()
}
builder.setPositiveButton("확인", listener)
builder.setNegativeButton("취소", null)
builder.show()
}
}
리사이클러뷰를 띄워주고, 플로팅버튼이 클릭됐을시에 custom으로 만든 dialog를 띄워준다.
이미지 클릭시 위에 탭에서 설명한 앨범에서 이미지를 불러오고, 입력받은 값들을 가져와 데이터 클래스에 형식에 맞춰서 넣어준 후에 adapter.notifyDataSetChanged()를 이용해서 바뀐 데이터를 업데이트 시켜준다.
전화번호부 앱에서 아이템을 오른쪽으로 swipe동작할시 전화연결이 가능하게 구현했다.
먼저 권한설정을 해준다.
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
그 후에 interface하나를 만들어준다.
package com.example.anycall
interface ItemTouchHelperListener {
fun onItemSwipe(position: Int)
}
그리고 클래스를 하나 만들어준다.
// ItemTouchHelper.Callback 클래스를 상속
class ItemTouchHelperCallback(val listener: ItemTouchHelperListener)
: ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
// 활성화된 이동 방향을 정의하는 플래그를 반환하는 메소드
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
// 드래그 방향
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
// 스와이프 방향
val swipeFlags = ItemTouchHelper.RIGHT
// 이동을 만드는 메소드
return makeMovementFlags(dragFlags, swipeFlags)
}
// 사용자에 의해 swipe될 때 호출
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
// 리스너의 onItemSwipe 메소드 호출
listener.onItemSwipe(viewHolder.adapterPosition)
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
TODO("Not yet implemented")
}
}
onMove는 아이템을 누르고 움직일시 동작하는 내용이다. 보통 순서를 바꿔주는데, 나는 이 동작은 사용하지않고 swipe만 사용했다.
마지막으로 어뎁터에서 이 인터페이스를 상속받아준다.
class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>(),
ItemTouchHelperListener {
...}
ItemTouchHelperListener를 상속받은 내용이다.
마지막으로 이 안에 내용을 추가해준다.
private val itemTouchHelper = ItemTouchHelper(ItemTouchHelperCallback(this))
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
this.recyclerView = recyclerView
itemTouchHelper.attachToRecyclerView(recyclerView)
}
override fun onItemSwipe(position: Int) {
val context = recyclerView?.context
val phoneNumber = mItems[position].phoneNum
if (ContextCompat.checkSelfPermission(context!!, Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_GRANTED
){
val callIntent = Intent(Intent.ACTION_CALL, Uri.parse("tel:$phoneNumber"))
context?.startActivity(callIntent)
} else{
// 퍼미션이 없는 경우에는 사용자에게 요청
ActivityCompat.requestPermissions(
context as Activity,
arrayOf(Manifest.permission.CALL_PHONE),
MyAdapter.MY_PERMISSIONS_REQUEST_CALL_PHONE
)
}
}
바로 전화를 걸려면 사용자가 권한을 허락했을시에 가능하게 만들어야 해서 권한을 허용했다면 전화를, 허용하지 않은 상태라면 permission을 요청해주었다.