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

d중첩 리사이클러뷰에서 하위리사이클러뷰 추가하기

0 추천

답변 주신 것처럼 코드를 수정해보았으나 코드가 이해가 완전히 되지 않은 것처럼 이해가 잘 안되어서 제 코드에서

수정을 조금씩 다시 하는식으로 코드를 손봤습니다. firstRecyclerView에 reConnectToAdapter 함수를 추가해서

추가하기 버튼을 누르면 모든 로그에서 추가세트가 생기는 것은 해결하였으나 

여전히 set를 추가하는 리사이클러뷰가 모든 로그에서 공유되고있는 것 같습니다..

 

 

[firstRecyclerView]

public class HealthFirstRecyclerViewAdapter extends RecyclerView.Adapter<HealthFirstRecyclerViewAdapter.ViewHolder>{
    ArrayList<Routine> routines = new ArrayList<>();     // 새로운 루틴을 받기 위한 배열
    ArrayList<SetsList> setsLists = new ArrayList<>();   // 세트수 추가를 위한 배열
    int setIndex = 0;

    public class ViewHolder extends RecyclerView.ViewHolder {

        /* 첫 번째 리사이클러뷰는 텍스트뷰 / 버튼 그리고 리사이클러뷰를 가지고 있음 */
        private RecyclerView setsRecyclerView;
        private TextView exerciseText;
        private Button addBtn;

        /**
         * 아이템 뷰를 저장하는 뷰홀더 클래스
         * @param itemView
         */
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            exerciseText = itemView.findViewById(R.id.registeredTextView);
            addBtn = itemView.findViewById(R.id.addWeight);
            setsRecyclerView = itemView.findViewById(R.id.todayLogRecyclerView);

            HealthSecondRecyclerViewAdapter adapter = new HealthSecondRecyclerViewAdapter(setsLists);
            setsRecyclerView.setAdapter(adapter);
        }

        public TextView getTextView() { return exerciseText; }

        public Button getButton() { return addBtn; }

        public RecyclerView getRecyclerView() { return setsRecyclerView; }
    }

    /**
     * 생성자에서 루틴 객체를 전달 받는다.
     * @param list
     */
    public HealthFirstRecyclerViewAdapter(ArrayList<Routine> list) { this.routines = list; }

    /**
     * 아이템 뷰를 위한 뷰홀더 객체를 생성하여 리턴한다.
     * @param parent
     * @param viewType
     * @return
     */
    @NonNull
    @Override
    public HealthFirstRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = null;

        v = LayoutInflater.from(parent.getContext()).inflate(R.layout.health_recyclerview_first, parent, false);

        return new HealthFirstRecyclerViewAdapter.ViewHolder(v);
    }

    /**
     * position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시.
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(@NonNull HealthFirstRecyclerViewAdapter.ViewHolder holder, int position) {
        Routine item = routines.get(position);

        holder.exerciseText.setText(item.getExerciseText());
        holder.addBtn.setText("추가");

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(holder.itemView.getContext());
        holder.getRecyclerView().setLayoutManager(linearLayoutManager);

        holder.getButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SetsList newSetsList = new SetsList(String.valueOf(setIndex++ +1) + "set", 0 + "kg", 0 + "reps");
                setsLists.add(newSetsList);
                reConnectToAdapter(holder);
            }
        });
    }

    public void reConnectToAdapter(ViewHolder holder) {
        HealthSecondRecyclerViewAdapter adapter = new HealthSecondRecyclerViewAdapter(setsLists);
        holder.getRecyclerView().setAdapter(adapter);
    }

    /**
     * 전체 데이터 개수 리턴.
     * @return
     */
    @Override
    public int getItemCount() { return routines.size(); }
}

 

[secondRecyclerView]

public class HealthSecondRecyclerViewAdapter extends RecyclerView.Adapter<HealthSecondRecyclerViewAdapter.ViewHolder>{
    ArrayList<SetsList> SetsList = new ArrayList<>();
    TextView setTextView, weightTextView, repsTextView;

    public class ViewHolder extends RecyclerView.ViewHolder{
        public ViewHolder(@NonNull View itemView) {

            super(itemView);

            setTextView = itemView.findViewById(R.id.set);
            weightTextView = itemView.findViewById(R.id.healthWeight);
            repsTextView = itemView.findViewById(R.id.reps);
        }

        public TextView getSetTextView() { return setTextView; }

        public TextView getWeightTextView() { return weightTextView; }

        public TextView getRepsTextView() { return repsTextView; }
    }

    public HealthSecondRecyclerViewAdapter(ArrayList<SetsList> list) {
        SetsList = list;
    }

    @NonNull
    @Override
    public HealthSecondRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = null;

        v = LayoutInflater.from(parent.getContext()).inflate(R.layout.health_recyclerview_second, parent, false);

        return new HealthSecondRecyclerViewAdapter.ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull HealthSecondRecyclerViewAdapter.ViewHolder holder, int position) {
        SetsList item = SetsList.get(position);
        holder.getSetTextView().setText(item.getSetsText());
        holder.getWeightTextView().setText(item.getWeightText());
        holder.getRepsTextView().setText(item.getRepsText());
    }

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

}

 

매력적인수박 (670 포인트) 님이 2021년 7월 27일 질문

1개의 답변

0 추천

ArrayList<SetsList> setsLists = new ArrayList<>(); 

setLists의  scope(범위)를 잘 보세요. HealthFirstRecyclerViewAdapter의 멤버 변수입니다. 즉, HealthFirstRecyclerViewAdapter안에서는 공유가 될 수 있는 인스턴스입니다. 그런데 onBindViewHolder 안에서는 로컬 변수로 setList를 생성하고 있지만  reconnectAdapter에서는 HealthFirstRecyclerViewAdapter에 있는 setLists 를 자식 어댑터에 넘겨주고 있습니다. 따라서 reconnectAdapter를 변경하시던가 onViewHolder를 변경하시던가 해야 겠네요.

@Override
    public void onBindViewHolder(@NonNull HealthFirstRecyclerViewAdapter.ViewHolder holder, int position) {
        Routine item = routines.get(position);
 
        holder.exerciseText.setText(item.getExerciseText());
        holder.addBtn.setText("추가");
 
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(holder.itemView.getContext());
        holder.getRecyclerView().setLayoutManager(linearLayoutManager);
 
        holder.getButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                reConnectToAdapter(holder);
            }
        });
    }
 
    public void reConnectToAdapter(ViewHolder holder) {
        SetsList newSetsList = new SetsList(String.valueOf(setIndex++ +1) + "set", 0 + "kg", 0 + "reps");
        setsLists.add(newSetsList);
        HealthSecondRecyclerViewAdapter adapter = new HealthSecondRecyclerViewAdapter(setsLists);
        holder.getRecyclerView().setAdapter(adapter);
    }

 

spark (227,530 포인트) 님이 2021년 7월 27일 답변
참고로 onBindViewHolder는 리사이클러뷰의 바인딩을 하게 되는 모든 row에 대해 실행이 됩니다. 따라서 HealthSecondRecyclerViewAdapter를 매번 생성하지 마시고 존재하지 않을 때만 생성하시던가, HealthFirstRecyclerViewAdapter.ViewHolder의 생성자에서 인스턴스를 생성하시고, setItems 등을 통해 adapter의 아이템들만 업데이트하는 형태가 불필요한 오브젝트 생성을 하지 않아서 더 효율적일 것 같습니다.
리사이클러뷰 추가질문입니다.
리사이클러뷰 피드백 보안입니다.
...