RecyclerView Viewholder reusing

两盒软妹~` 提交于 2019-12-23 12:47:44

问题


I am creating a RecyclerView which will expand itself when the user touches it and closes itself when the user touches it again. Below is my code:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecViewHolder> {
    ArrayList<String> values;
    ArrayList<Integer> expandedPosition;
    public static class RecViewHolder extends RecyclerView.ViewHolder {
        ...
        private boolean resultsOpened = false;
        ...
        RelativeLayout favHeaderLayout;
        RelativeLayout favResultsLayout;

        public RecViewHolder (View itemView) {
            super(itemView);
            favHeaderLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!resultsOpened) {
                        expandLayout();
                    } else {
                        favResultsLayout.setVisibility(View.GONE);
                        resultsOpened = false;
                    }
                }
            });

        }

        public void expandLayout() {
            favResultsLayout.setVisibility(View.VISIBLE);
            resultsOpened = true;
            //I populate my expanded layout here
        }
    }

    public RecyclerViewAdapter (Context context, ArrayList<String> values) {
        this.context = context;
        this.values= values;
    }

    @Override
    public RecViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_file, parent, false);
        RecViewHolder recViewHolder= new RecViewHolder(v);
        return recViewHolder;
    }

    @Override
    public void onBindViewHolder(RecViewHolder recViewHolder , int position) {
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

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

}

When I touch the first view, it should expand itself. However, when the adapter has more data and I touch the first view, the view expands and another view at the bottom of the RecyclerView (e.g. the 8th view) expands too. How do I ensure that only the view that have been touched expand the the other stays close?

EDIT

I've tried storing the expanded Views position in an arraylist and in onBindViewHolder, check which views are expanded and expand them only:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecViewHolder> {
    ArrayList<String> values;
    ArrayList<Integer> expandedPosition;
    public static class RecViewHolder extends RecyclerView.ViewHolder {
        ...
        private boolean resultsOpened = false;
        ...
        RelativeLayout favHeaderLayout;
        RelativeLayout favResultsLayout;

        public RecViewHolder (View itemView) {
            super(itemView);


        }

    }

    public RecyclerViewAdapter (Context context, ArrayList<String> values) {
        this.context = context;
        this.values= values;
    }

    @Override
    public RecViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_file, parent, false);
        RecViewHolder recViewHolder= new RecViewHolder(v);
        return recViewHolder;
    }

    @Override
    public void onBindViewHolder(RecViewHolder recViewHolder , int position) {
        recViewHolder.favResultsLayout.setVisibility(View.GONE);
        for(int i= 0; i < expandedPosition.size(); i ++){
            recViewHolder.favResultsLayout.setVisibility(View.VISIBLE);
        }
        recViewHolder.favHeaderLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                     if (!expandedPosition.contains(position)) {
                        expandLayout(recViewHolder);
                        expandedPosition.add(position);
                    } else {
                        recViewHolder.favResultsLayout.setVisibility(View.GONE);
                        for(int i = 0; i < expandedPosition.size(); i ++){
                            if (expandedPosition.get(i) == position){
                                    expandedPosition.remove(i);
                            }
                        }
                    }
                }
            });
    }
    public void expandLayout() {
            favResultsLayout.setVisibility(View.VISIBLE);
            //I populate my expanded layout here
        }
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

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

}

Still no luck :(


回答1:


As the class name says it is all about recycling ...

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecViewHolder> {
    ArrayList<String> values;
    SparseBooleanArray expanded = new SparseBooleanArray();
    public static class RecViewHolder extends RecyclerView.ViewHolder {
        //EDIT!!!!!
        public RecViewHolder (View itemView, final RecyclerViewAdapter adapter) {
        //rest of the code ...
        favHeaderLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { 
                final int currentPosition = getAdapterPosition();
                //is a view at current position expanded?
                if(adapter.expanded.get(currentPosition ))
                    //if so it shouldn't be
                    adapter.expanded.delete(getAdapterPosition(currentPosition));
                else
                    //if not, expand
                    adapter.expanded.put(currentPosition, true);
                //wheeee inform the adapter to rebind
                adapter.notifyItemChanged(currentPosition);
                //setupExpanded(expanded.get(currentPosition)); 
            }
        });
        }
        protected void setupExpanded(boolean state) {
        //ONLY hide show layouts based on state
        }
    }
    @Override
    public RecViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_file, parent, false);
        RecViewHolder recViewHolder= new RecViewHolder(v, this);
        return recViewHolder;
    }

    @Override
    public void onBindViewHolder(RecViewHolder recViewHolder , int position)    {
        //this line should be self explanatory
        recViewHolder.setupExpanded(expanded.get(position));
    }

    //rest of the code
}


来源:https://stackoverflow.com/questions/30759016/recyclerview-viewholder-reusing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!