마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

EditText가 포커싱 되었을때 위치값을 알 수 있는 방법이 있을까요?

0 추천

Epoxy를 사용중입니다( 리사이클러뷰 대체)

제 기능이 아이템을 추가 삭제하는 기능이 많아 동적으로 변화가 많은 편인데,

아이템이 충분히 추가되었을때 EditText에 값을 입력후 스크롤하거나 추가로 아이템을 추가하면

EditText에 있던 값이 없어지거나 다른 아이템에 랜덤으로 배치되는 현상이 생겼습니다.

이걸 해결하기 위해서

TextWatcher를 사용해서 입력후 ViewModel 을 거쳐 repository에 있는 Model에 저장한 후에

Epoxy(RecyclerView)에서 스크롤이나 아이템 추가로인한 재빌드가 될때 값을 불러와 그대로 값을 

셋팅할 수 있도록 생각중인데요,

문제가 두가지? 정도있습니다.

 

문제1. 사진속의 색깔 박스하나하나가 아이템인데 이때 EditText에 포커싱되었을떄

이 해당 위치에 맞는 아이템을 어떻게 찾는지 궁금합니다.

정확히는 어떻게 찾는지 보다는 버튼이 클릭되었을때 setOnClickListener이 호출되는 것처럼

EditText에 포커싱 되었을때 콜백함수같은것이 있는지 궁금합니다.

위치는 아이템 내에 저장한 UUID같은걸로 비교해서 찾으려고합니다..

 

문제2. 위에서 아이템에 저장된 UUID로 찾는다고 헀는데 여기서 또한 문제가

이 아이템에 저장된 ID는 사진속의 박스(모델)하나에 대한 ID입니다.

그런데 박스 안에는 EditText가 두가지가 있습니다. 두가지 다 각각 다른 프로퍼티에 저장되어야할텐데,

이 각각의 위치를 어떻게 알아야하는지 궁금합니다.

 

혹은 더 좋은 방법이 있다면 알려주세요ㅠ

그리고 옳은 방법인지는 모르겠으나 TextWatcher는 ViewModel 혹은 Repository에 위치할 예정입니다..

-----------------

data class RoutineDetailModel(
    val id: String // UUID 사용
    val set: Int, // 세트
    val weight: String,
    val reps: String = "1") {
}

 

// 가공된 데이터를 RV(Epoxy)에 나열하기 위한 클래스
sealed class RoutineItem(
    val id: String
) {
    class RoutineModel(
        id: String, // Id, UUID 사용
        val workout: String, // 운동 종목
        val unit: String, // 무게 단위 (kg or lbs)
//        var routineDetail: List<DetailModel> = listOf() // 단순 RV에 보여주기 위한것이므로 여기서는 상세 프로퍼티가 필요없을듯
    ) : RoutineItem(id)

    class DetailModel(
        id: String, // Id, UUID 사용
        val set: Int, // 세트
        var weight: String,
        val reps: String = "1",
    ) : RoutineItem(set.toString())
}

 

 

 

codeslave (3,940 포인트) 님이 2021년 11월 20일 질문
다른 건 모르겠고 확실한 거 하나는 TextWatcher는 ViewModel 에 위치하시면 안되고  View에 위치해야 합니다. ViewHolder가 제일 적합한 위치이긴 한데, 상황에 따라 Adapter나 Activity/Fragment 등도 생각해 볼 수 있을 것 같구요. 경험으로는 TextWatcher를 removeTextChangeListener를 안해주면  메모리누수가 생길 때가 종종 있더라구요.

참고로 상당히 많은 아이템이 들어갈 수 있는 수정화면을 님처럼 리사이클러뷰 형태로 두는 건 모바일에서는 잘 사용하지 않긴 합니다. 사용자 경험은 잘 모르겠지만, 일단은 컨트롤하기 상당히 짜증나기 때문이죠. Jetpack Compose같이 View를 Readonly로 만들지 않을 경우에는 상당히 제어하기 힘들 화면입니다. 저라면 그냥 팝업 같은 것을 띄우거나 별도의 화면에서 수정하는 걸로 디자인을 바꿀 것 같아요.
1. 음..그런데 ViewHolder에 위치하게되면 View이서 데이터를 아이템에 넣고 수정하는 로직을 하게 될텐데 mvvm패턴에 문제는 없나요? 저는 그 Epoxy(RecyclerView)에는 그 데이터를 넣고 수정하고 하는 로직은 아예안넣고 순수 다 정리된 아이템들만 넣어 나열될수 있게하려했거든요..

2.어떠한 화면을 파업을 띄우거나 별도의 화면에서 한다는 말씀인가요?
1. TextWatcher는 안드로이드 뷰에서 사용되는 클래스입니다. 그렇기 때문에 ViewModel에서 사용을 하지 않는 겁니다. ViewModel에 TextWatcher를 직접 사용하지 마시고  ViewHolder에서 넘어온 콜백을 사용하세요.
class MyViewHolder (itmeView: View, val onTextChanged: (String) -> Unit): RecyclerView.ViewHolder(itmeView) {

     init {
         editText.doAfterChanged { edit ->
            val text = edit?.toString() ?: ""
           onTextChanged(text)
         }
     }
}

2. 모발일의 특성상 한 화면에서 리스트 + CRUD가 다 일어나면 핸들링 기본적으로 힘들어져요.
위처럼 리사이클러뷰에서 포커스 관리를 하시려면 모델쪽에서 이 포커스에 대한 정보도 관리해야 할 것으로 보여요. 그래야 리사이클러뷰가 리프레쉬되고나서 다시 복구해 줄 수 있지않나 하는 생각이 드네요.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...