recyclerview 안에 아이템이 스크롤하면 복제생성이 되네요 왜이럴까요??

조회수 3798회

리사이클러뷰 안에 써클이 1개 ~ 3개를 넣어서 증가시켜주게 만들었는데

위아래로 위 혹은 아래의 아이템을 복제해서 만든은데 이게 왜이러는걸까요??

메인 액티비티

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private List data = new ArrayList();
    private Object[][] obj = new Object[][]{{Color.BLUE, "첫"}, {Color.RED, "2"}, {Color.BLACK, "3"}};
    private Object[][] obj2 = new Object[][]{{Color.BLUE, "첫"}, {Color.GREEN, "0"}};
    private Object[][] obj3 = new Object[][]{{Color.BLUE, "a"}, {Color.YELLOW, "b"}, {Color.CYAN, "c"}};
    private Object[][] obj4 = new Object[][]{{Color.RED, "가"}, {Color.BLUE, "나"}/*, {Color.RED, "다"}*/};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        RecycleAdt.Item fir = new RecycleAdt.Item(RecycleAdt.HEADER, 1);
        RecycleAdt.Item sec = new RecycleAdt.Item(RecycleAdt.HEADER, 3);
        RecycleAdt.Item thir = new RecycleAdt.Item(RecycleAdt.HEADER, 5);
        data.add(fir);
        fir.item = new ArrayList();
        for (int i = 0; i < 5; i++) {
            fir.item.add(new RecycleAdt.Item(RecycleAdt.CHILD, obj, 4.5f, 1));
        }
        fir.item.add(new RecycleAdt.Item(RecycleAdt.MORE, 1, false));
        data.add(sec);
        sec.item = new ArrayList();
        for (int i = 0; i < 2; i++) {
            sec.item.add(new RecycleAdt.Item(RecycleAdt.CHILD, obj2, 8.4f, 3));
        }
        sec.item.add(new RecycleAdt.Item(RecycleAdt.MORE, 3, false));
        data.add(thir);
        thir.item = new ArrayList();
        for (int i = 0; i < 5; i++) {
            thir.item.add(new RecycleAdt.Item(RecycleAdt.CHILD, obj3, 1.8f, 5));
        }
        thir.item.add(new RecycleAdt.Item(RecycleAdt.CHILD, obj4, 1.8f, 5));
        thir.item.get(thir.item.size() - 1).isSPECIAL = true;
        thir.item.add(new RecycleAdt.Item(RecycleAdt.MORE, 5, false));

        recyclerView.setAdapter(new RecycleAdt(data));
    }
}
}

리사이클러뷰 어댑터

public class RecycleAdt extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final int HEADER = 1;
    public static final int CHILD = 2;
    public static final int MORE = 3;
    private List<Item> data;

    public RecycleAdt(List<Item> data) {
        this.data = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v;
        LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        switch (viewType) {
            case HEADER:
                v = inflater.inflate(R.layout.header, parent, false);
                return new Header(v);
            case CHILD:
                v = inflater.inflate(R.layout.child, parent, false);
                return new Child(v);
            case MORE:
                v = inflater.inflate(R.layout.more, parent, false);
                return new More(v);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        final Item item = data.get(position);
        switch (item.type) {
            case HEADER: {
                final Header h = (Header) holder;
                h.headerItem = item;
                h.holder.setVisibility(View.VISIBLE);
                h.title.setText(item.headerText);
                ((HeaderContainer) h.layout_color).init(item.where, 1);
                if (!item.iscreated) {
                    item.iscreated = !item.iscreated;
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            int pos = data.indexOf(h.headerItem);
                            int idx = pos + 1;
                            Log.e("1", item.item.size() + "");
                            for (Item i : item.item) {
                                data.add(idx, i);
                                Log.e("1", pos + " : " + idx + "");
                                idx++;
                            }
                            notifyItemRangeInserted(pos + 1, idx - pos - 1);
                            item.item = null;
                        }
                    }, 1);
                }
                break;
            }
            case CHILD: {
                Child c = (Child) holder;
                c.top.setVisibility(View.VISIBLE);
                if (item.isSPECIAL) {
                    ((HeaderContainer) c.classBar).init(-1, 3);
                    ((ExitContainer) c.delbar).init(-1);
                    c.top_cut.setBackgroundColor(0xffFDB500);
                    c.bottom_cut.setBackgroundColor(0xffFDB500);
                    c.class_title.setText(position + "");
                } else {
                    c.class_title.setText("평균클래스");
                    ((HeaderContainer) c.classBar).init(item.where, 3);
                    ((ExitContainer) c.delbar).init(item.where);
                    switch (item.where) {
                        case 1: {
                            c.top_cut.setBackgroundColor(0xff7159b3);
                            c.bottom_cut.setBackgroundColor(0xff7159b3);
                            break;
                        }
                        case 2: {
                            c.top_cut.setBackgroundColor(0xff7159b3);
                            c.bottom_cut.setBackgroundColor(0xff7159b3);
                            break;
                        }
                        case 3: {
                            c.top_cut.setBackgroundColor(0xffeb78a0);
                            c.bottom_cut.setBackgroundColor(0xffeb78a0);
                            break;
                        }
                        case 4: {
                            c.top_cut.setBackgroundColor(0xffeb78a0);
                            c.bottom_cut.setBackgroundColor(0xffeb78a0);
                            break;
                        }
                        case 5: {
                            c.top_cut.setBackgroundColor(0xff59a3b5);
                            c.bottom_cut.setBackgroundColor(0xff59a3b5);
                            break;
                        }
                        case 6: {
                            c.top_cut.setBackgroundColor(0xff59a3b5);
                            c.bottom_cut.setBackgroundColor(0xff59a3b5);
                            break;
                        }
                    }
                }
                for (int i = 0; i < item.childColor.length; i++) {
                    c.viewArr[i].setVisibility(View.VISIBLE);
                    c.img[i].setBackgroundColor(item.childColor[i]);
                    c.text[i].setText(item.childText[i]);
                }
                break;
            }
            case MORE: {
                More m = (More) holder;
                ((HeaderContainer) m.layout_color).init(item.where, 2);
                break;
            }
        }
    }

    @Override
    public int getItemViewType(int position) {
        return data.get(position).type;
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public static class Item {
        public int type;
        public List<Item> item;
        public int where; //1:나를찜한팀 , 2:내가찜한팀 , 3:나를찜한카드 , 4:내가찜한카드 ,5:응답대기 , 6:응답요청
        public String headerText;
        public int childColor[];
        public String childText[];
        public float team_rating;
        public boolean iscreated;
        public boolean isSPECIAL;

        public Item(int type, Object[][] userlist, float rating, int where)
        {
            this.type = type;
            this.team_rating = rating;
            this.childColor = new int[userlist.length];
            Log.e(",", childColor.length + "");
            this.childText = new String[userlist.length];
            this.where = where;

            for (int i = 0; i < userlist.length; i++) {
                childColor[i] = (int) userlist[i][0];
                childText[i] = (String) userlist[i][1];
            }
        }

        public Item(int type, int where) {
            this.type = type;
            this.where = where;
            if (where == 1 || where == 2) {
                if (where == 1)
                    this.headerText = "나를찜한팀";
                else
                    this.headerText = "내가찜한팀";
            } else if (where == 3 || where == 4) {
                if (where == 3)
                    this.headerText = "나를찜한카드";
                else
                    this.headerText = "내가찜한카드";
            } else if (where == 5 || where == 6) {
                if (where == 5)
                    this.headerText = "응답대기";
                else
                    this.headerText = "응답요청";
            }
        }

        /**
         * OverLoading
         */
        public Item(int type, int where, boolean OVERLOADING) {
            this.type = type;
            this.where = where;
        }
    }
}


1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    RecyclerView의 아이템뷰는 효율적인 메모리 사용 및 성능을 위해 스크롤 시 매번 뷰를 생성하지 않습니다. 화면에 보이는 개 수 만큼만 뷰를 생성하고, 이를 재활용하는데요. 말씀하신 현상은 뷰가 재활용되면서 기존의 뷰 상태가 여전히 유지되고 있기 때문에 발생하는 것으로 보입니다. '''onBindViewHolder'()''에서 뷰를 제대로 업데이트 하는지 확인이 필요합니다. 코드가 복잡해서 문제를 발견하기 쉽지 않다면 최소 샘플을 만들어서 문제가 없는 상태에서 코드를 하나씩 붙여나가 보시기 바랍니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)