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

리사이클러 뷰 질문입니다.

0 추천

액티비티에서 버튼 클릭을 통해 리사이클러 뷰의 내용을 한번에 전달 하려고 합니다.

public Damage_VO getItem(int position) {
    return arrayList.get(position);
}

이런식으로 어댑터에 선언을 해두고,

액티비티에서 for 문으로 Damage_VO 의 리스트에서 값을 따로 저장하고있는데

여기서 발생한 문제가 리스트의 갯수가 많아지면(스크롤이 생겨 화면을 벗어날 정도의 개수)

position 값을 제대로 불러오지 못하고 있습니다. 재사용 문제 때문인것 같아

@Override
public int getItemViewType(int position) {
    return position;
}

를 어댑터에 추가해 주었고, 스크롤을 맨 아래까지 한번 내린 뒤에 처리를 하면

삭제, 전달 등의 기능이 잘 작동을 하는데 그렇지 않을 때 자꾸 오류가 납니다.

스크롤을 해서 화면에 한번은 띄워야 position 값이 제대로 저장 되는 것 같은데,

스크롤을 하지 않고서 처음부터 전체 리스트의 position 값을 셋 시킬 수는 없을까요?

화면에서 리스트의 요소를 저장하는 함수입니다.

private void getListView() {
    for (int i = 0; i < pihae_list.size(); i++) {
        List<String> list = new ArrayList<>();

        Damage_VO item = new Damage_VO();
        item = mAdapter1.getItem(i);

        String regist_gubun = item.getGubun().toString();
        String regist_sulbi_gubun = item.getSulbiGubun().toString();
        // 중략
    }
}

 

직접 수동으로 스크롤을 하지않고, 처음부터 position 값을 할당할 수 있는 방법이 있을까요?

(글쓰기 길이가 넘어가서 코드 전문을 첨부 시키지 못해 죄송합니다)

하부 (160 포인트) 님이 2022년 2월 24일 질문

1개의 답변

+1 추천
 
채택된 답변
먼저 getItemViewType은 각 row에 사용될 레이아웃의 리소스  ID를 리턴하는 함수입니다. 여기서 리턴된 값이 onCreateViewHolder의 파라미터인 viewType으로 전달됩니다. 따라서 추가하신 getItemViewType은 삭제하시는게 맞는 것 같구요.

그리고 리사이클러뷰에 있는 내용을 다른 화면에서 사용하시려는 부분은  리사이클러뷰는 단순히 화면에 보여지는 것이므로 그냥 놔두시고, 리사이클러뷰에 전달되어진 데이터를 가진 데이터 소스를 재사용하는 것이 바람직합니다.

즉 데이터를 관리할 클래스를 하나 만드시고 여기에 조회, 추가, 수정, 삭제 메소드를 구현하세요. 이 클래스의 인스턴스를 singleton으로 만드시고 이 데이터가 필요한 곳은 여기에서 데이터를 가져다 사용하세요.
spark (224,800 포인트) 님이 2022년 2월 24일 답변
하부님이 2022년 2월 25일 채택됨
답변감사합니다!
우선 본문에 설명이 조금 부족했던것 같습니다.

제가 getItemViewType 를 사용하게 된게, 리사이클러뷰에서 출력되는 리스트의 구성에 checkbox가 들어가서 checkbox가 체크된 상태로 스크롤을 내렸다 올렸다 하면 체크상태가 풀리는 오류가 있었고, 이러한 오류를 getItemViewType를 통해 해결하여서 추가해 두었습니다. getItemViewType를 사용하지않고 이러한 재사용 문제를 해결할수 있을까요?

그리고 마지막에 적어주신 말씀이 잘 이해가 안가서 그러는데 자세하게 설명 부탁 드려도 될까요?
getItemViewType 안에서 position을 리턴하는 건 문제가 생길 가능성이 많은 코드입니다. 아이템 개수가 동적으로 변하거나 하면 바로 문제가 생길 수 있어요. 아래처럼,  아이템이 뷰타입을 리턴하게 만드는 형태로 처리하면,
아이템 개수가 바뀌어도 나중에 문제가 생길 일이 없을 듯 합니다.
@Override
public int getItemViewType(int position) {
    return getitem(position).getViewType();  // layout id를 리턴
}

그리고 다른 부분은 데이터를 처리하는 클래스를 분리하라는 말씀입니다.  예를 들어 어댑터에 들어가는 데이터를

public class DisasterDataSource {
     public static DisasterDataSource.getInstance() {
         ...
     }
     priate DisasterDataSource() {}
   
     public List<Damage_VO> getDisasters() {
         ...
     }
}

처럼 싱글톤으로 만드시고, List<Damage_VO>를 리턴하도록 만드세요.

이제 이걸 여러 군데서 공유해서 사용하시면 됩니다.
public class Activity1 extends AppCompatActivity {
   private final DisasterDataSource dataSource = DisasterDataSource.getInstance();
}

public class Activity2 extends AppCompatActivity {
   private final DisasterDataSource dataSource = DisasterDataSource.getInstance();
}

public class Activity3 extends AppCompatActivity {
   private final DisasterDataSource dataSource = DisasterDataSource.getInstance();
}

이렇게 하시면 어디에서든지 데이터를 사용할 수 있습니다.

아래 리포에 가시면, 다른 분이 유사한 질문을 하셔서 예제를 만들어 둔 것이 있습니다.

질문: https://www.masterqna.com/android/100145/%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0%EB%81%BC%EB%A6%AC-%EC%96%91%EB%B0%A9%ED%96%A5%EC%9C%BC%EB%A1%9C-%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%A3%BC%EA%B3%A0-%EB%B0%9B%EA%B2%8C-%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%8A%B5%EB%8B%88%EB%8B%A4

리포:
https://github.com/krpot/VerySimpleUserIdShare/tree/develop

질문을 잘 읽어보시면, 동일하게 데이터를 앱 내의 여러 곳에서 공유하는 문제입니다. 이걸 처리하는 방법 중의 하나를 샘플로 작성한 것입니다.
답변 감사합니다! 확실히 말씀 하신대로, 리스트의 크기가 변하면 생기는 오류도 있었는데 정확하게 짚어주셨어요... 답변주신것을 토대로 좀 더 이해하고 수정해보겠습니다. 감사합니다!
...