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

리사이클러뷰 list add 질문

0 추천
새 프로젝트로 해서 해봤는데 안돼서 다시 질문드립니다!
enerigpy (2,110 포인트) 님이 2023년 2월 17일 질문
네네 근데

ItemData selectedItem = dataList.get(position);
if(selectedItem.toggleChecked2(checked2)) {
     openUrl(selectedItem.getLink());       
}

이 부분은 어디 클래스에 넣어야 하는건가요?
이미 윗 댓글에 있는데요. MyRecyclerViewClickListener에 onButton2Clicked를 추가하고 구현했는데요. @Override 어노테이션을 보시면 이해가 가실거예요.
네 답변 잘받았습니다.

근데 계속해서 코드가 꼬이는거 같아서요

holder.button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onOpenLink(holder.getAdapterPosition());
                }
            }
        });

이부분에서 string이 아니여서                      mListener.onOpenLink(String.valueOf(holder.getAdapterPosition()));
이렇게 바꿔줘야 하는거같고

@Override
    public void onButton2Clicked(int position) {
        ItemData selectedItem = dataList.get(position);
        selectedItem.toggleChecked2(checked2);
        adapter.notifyItemChanged(position);

        if(selectedItem.getChecked2(checked2)) {
            onOpenLink(selectedItem.getLink());
        }
    }

여기에서 getLink에 대한 link를 리턴하는걸 구현했는데 position에 대해 그거에 맞는 배열로 불러들어야 하는 문제가 있네요.

public String[] getLink() {
        String[] link = {"https://www.youtube.com/watch?v=a_k-dCgubFo",
        "https://youtu.be/"};

        return link;
    }
자바 생성자만 사용할 줄 알면 해결될 것 같은데요. 생성자에 link를 전달하세요.

public class ItemData {
     private int image;  
     private boolean checked1;
     private boolean checked2;
     private String link;

     public ItemData(int image, String link) {
         this.image = image;
         this.link = link;
     }
   
}

new ItemData(R.drawable.ic_1, "https://link1");
new ItemData(R.drawable.ic_2, "https://link2");

ItemData를 화면에 보여질 데이터로 취급하세요.
//main
dataList.add(new ItemData(R.drawable.ic_sc_btn1, "https://www.youtube.com/watch?v=a_k-dCgubFo"));
dataList.add(new ItemData(R.drawable.ic_sc_btn,  "https://youtu.be/"));

private List<ItemData> getItems() {
        return Arrays.asList(new ItemData(R.drawable.ic_launcher_background, "https://youtu.be/"), new ItemData(R.drawable.ic_launcher_foreground, "https://www.youtube.com/watch?v=a_k-dCgubFo"));
    }

// item class
public ItemData(int image, String link) {
        this(image, false, false, link);
    }

    public ItemData(int image, boolean checked, boolean checked2, String link) {
        this.image = image;
        this.checked = checked;
        this.checked2 = checked2;
        this.link = link;
    }

public String getLink() {
        return link;
    }

// adapter
holder.button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onOpenLink(String.valueOf(holder.getAdapterPosition()));
                }
            }
        });

url누를때 디버깅 해보니 link에 null이 반환되는데 뭐가 문제일까요?

1개의 답변

+1 추천
 
채택된 답변

onOpenLink에 필요한 파라미터는 URL string입니다. 그런데 님의 코드를 보면

holder.button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    String url = String.valueOf(holder.getAdapterPosition()); // 버그. 이건 URL이 아님.
                    mListener.onOpenLink(url);
                }
            }
        });

holder.getAdapterPosition()을 String으로 변환해서 넘기고 있습니다. 이건 URL이 아니고, 아이템의 위치예요. onOpenLink를 사용하려면 getLink()를 가져와서 넘기셔야 하고,  holder.getAdapterPosition()을 사용하려면, 제가 했던 것처럼 onButton2Checked 왁 같은 형태로 아이템의 위치를 넘기셔야 겠죠.

코드를 작성하실 때 클래스 이름이나 메소드 이름, 파라미터 이름 등을 잘 만드세요. 그리고 코드를 읽으실 때는 영어 문장이라고 생각하시고 읽도록 해보세요. 자연스러운 영어문장 처럼 될 수록 좋고 깔끔한 코드가 나옵니다.

spark (227,530 포인트) 님이 2023년 2월 19일 답변
enerigpy님이 2023년 2월 19일 채택됨
네네 처음에 저거대로 하려고 했는데 long클릭으로 하지않고 setonclick으로 하려고 해서요 근데 longclick으로 했을 때는

holder.button2.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mListener != null) {
                    mListener.onOpenLink(link);
                    return true;
                }
                return false;
            }
        });

했는데 link에 null만 넘어가네요??
link라는 변수를 어떻게 가져왔는지 모르겠네요. 님처럼 하고 싶으면 아래와 같은 코드가 되어야 할 것 같은데요.

if (mListener == null) return false;

int pos = holder.getAdapterPosition();
String url = getItem(pos).getLink();
mListener.onOpenLink(link);
return true;
오 드디어 해결한거 같네요 감사해요!

url말고 link로 다 통일시켜서 했어요 그래도 상관없겠죠?
아 그리고 만약에 link 연결 막아두려면 방법이 있을까요? "" 이렇게 하면 당연히 안되고 있어서요!
버튼이 체크된 상태에서만 링크를 열고 싶은거죠?

f (mListener == null) return false;

int pos = holder.getAdapterPosition();
ItemData item = getItem(pos).
boolean canOpenLink = !item.getChecked2();

String url = canOpenLink ? item.getLink() : null;
mListener.onOpenLink(link);
return true;

// Activity
@Override
public void onOpenLink(@Nullable String link) {
     ....
     if (link == null) return;
     openLink(link);
}
추가 질문이 있으시면 새 질문으로 해주시면 읽기 편할 것 같네요.
...