Choice Mode in a RecyclerView?

后端 未结 3 554
时光说笑
时光说笑 2020-12-03 01:15

I\'m trying to figure out how to achieve the same effect of

mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

in a RecyclerView implementat

相关标签:
3条回答
  • 2020-12-03 01:45

    You can follow this:

    – Data (String name, boolean selected)

    – Adapter with itemClickListener

    – Activity or fragment

    – activity_main (recyclerView)

    – list_item (TextView, CheckBox)

    Data

    public class MultipleData {
    
        private String mTitle;
        private boolean mBoolean;
    
        public MultipleData(String title, boolean mBoolean) {
            this.mTitle = title;
            this.mBoolean = mBoolean;
        }
    
        public String getTitle() {
            return mTitle;
        }
    
        public void setTitle(String mTitle) {
            this.mTitle = mTitle;
        }
    
        public boolean isBoolean() {
            return mBoolean;
        }
    
        public void setBoolean(boolean mBoolean) {
            this.mBoolean = mBoolean;
        }
    }
    

    Your views activity_main.xml (recyclerView)

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.thedeveloperworldisyours.fullrecycleview.multiple.MultipleFragment">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/multiple_fragment_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </FrameLayout>
    

    and list_item.xml (TextView, CheckBox)

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <TextView
            android:id="@+id/multiple_list_item_text"
            android:layout_width="match_parent"
            android:layout_height="90dp"
            android:text="@string/app_name"
            android:typeface="monospace"
            android:layout_toLeftOf="@+id/multiple_list_item_check_button"
            android:gravity="center"
            android:textSize="@dimen/multiple_list_item_size_rock_stars"/>
    
        <RadioButton
            android:id="@+id/multiple_list_item_check_button"
            android:layout_width="wrap_content"
            android:layout_height="90dp"
            android:layout_alignParentRight="true"
            android:checked="false"
            android:clickable="false"
            android:focusable="false" />
    
    </RelativeLayout>
    

    Adapter with ClickListener

    public class MultipleRecyclerViewAdapter extends RecyclerView
            .Adapter<MultipleRecyclerViewAdapter
            .DataObjectHolder> {
    
        private List<MultipleData> mList;
        private static MultipleClickListener sClickListener;
    
        MultipleRecyclerViewAdapter(List<MultipleData> mList) {
            this.mList = mList;
        }
    
        static class DataObjectHolder extends RecyclerView.ViewHolder
                implements View
                .OnClickListener {
    
            TextView mTextView;
            RadioButton mRadioButton;
    
             DataObjectHolder(View itemView) {
                super(itemView);
                mTextView = (TextView) itemView.findViewById(R.id.multiple_list_item_text);
                mRadioButton = (RadioButton) itemView.findViewById(R.id.multiple_list_item_check_button);
                itemView.setOnClickListener(this);
            }
    
            @Override
            public void onClick(View v) {
                sClickListener.onItemClick(getAdapterPosition(), v);
            }
        }
    
        void changedData(int position) {
                if (mList.get(position).isBoolean()) {
                    mList.get(position).setBoolean(false);
                } else {
                    mList.get(position).setBoolean(true);
                }
            notifyDataSetChanged();
        }
    
        void setOnItemClickListener(MultipleClickListener myClickListener) {
            this.sClickListener = myClickListener;
        }
    
        @Override
        public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.multiple_list_item, parent, false);
    
            DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
            return dataObjectHolder;
        }
    
        @Override
        public void onBindViewHolder(DataObjectHolder holder, int position) {
            holder.mTextView.setText(mList.get(position).getTitle());
            holder.mRadioButton.setChecked(mList.get(position).isBoolean());
        }
    
        @Override
        public int getItemCount() {
            return mList.size();
        }
    
        interface MultipleClickListener {
            void onItemClick(int position, View v);
        }
    
    
    }
    

    Activity or fragment

    public class MultipleFragment extends Fragment implements MultipleRecyclerViewAdapter.MultipleClickListener{
    
        MultipleRecyclerViewAdapter mAdapter;
    
        public MultipleFragment() {
            // Required empty public constructor
        }
    
        public static MultipleFragment newInstance() {
            return new MultipleFragment();
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.multiple_fragment, container, false);
    
            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.multiple_fragment_recycler_view);
    
            MultipleData hendrix = new MultipleData("Jimi Hendrix", false);
            MultipleData bowie = new MultipleData("David Bowie", false);
            MultipleData morrison = new MultipleData("Jim Morrison", false);
    
            MultipleData presley = new MultipleData("Elvis Presley", false);
            MultipleData jagger = new MultipleData("Mick Jagger", false);
            MultipleData cobain = new MultipleData("Kurt Cobain", false);
    
            MultipleData dylan = new MultipleData("Bob Dylan", false);
            MultipleData lennon = new MultipleData("John Lennon", false);
            MultipleData mercury = new MultipleData("Freddie Mercury", false);
    
            MultipleData elton = new MultipleData("Elton John", false);
            MultipleData clapton = new MultipleData("Eric Clapton", false);
    
            List<MultipleData> list = new ArrayList<>();
            list.add(0, hendrix);
            list.add(1, bowie);
            list.add(2, morrison);
    
            list.add(3, presley);
            list.add(4, jagger);
            list.add(5, cobain);
    
            list.add(6, dylan);
            list.add(7, lennon);
            list.add(8, mercury);
    
            list.add(9, elton);
            list.add(10, clapton);
    
            mAdapter = new MultipleRecyclerViewAdapter(list);
            recyclerView.setAdapter(mAdapter);
            recyclerView.setHasFixedSize(true);
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    
            recyclerView.setLayoutManager(layoutManager);
            mAdapter.setOnItemClickListener(this);
    
            return view;
        }
    
        @Override
        public void onItemClick(int position, View v) {
            mAdapter.changedData(position);
        }
    }
    

    You can see this example in GitHub and this post for multiple choice, and this post for single choice Happy code!!!

    0 讨论(0)
  • 2020-12-03 01:51

    There is no built-in support for a "choice mode" structure with RecyclerView. Your options are to either roll it yourself or use a third-party library that offers it. The DynamicRecyclerView library offers choice modes, but I have not tried it.

    This sample app demonstrates implementing it yourself, in this case using the activated state to indicate which is the current choice. The overall pattern is:

    • Have your RecyclerView.ViewHolder detect a UI operation that indicates a choice (click on a row? click on a RadioButton in the row? etc.).

    • Keep track of the selection at the level of your RecyclerView.Adapter. In my case, a ChoiceCapableAdapter handles that, in conjunction with a SingleChoiceMode class that implements a ChoiceMode strategy.

    • When a choice is made, update the newly-chosen row to reflect the choice and update the previously-chosen row to reflect that it is no longer chosen. findViewHolderForPosition() on RecyclerView can help here -- if you track the position of the last choice, findViewHolderForPosition() can give you the ViewHolder for that choice, so you can "un-choose" it.

    • Keep track of the choice across configuration changes, by putting it in the saved instance state of the activity or fragment that is managing the RecyclerView.

    0 讨论(0)
  • 2020-12-03 01:58

    I've created a library for this kind of choice mode applied to the RecyclerView, maybe it can help:

    Description

    This library has been created to help the integration of a multi-choice selection to the RecyclerView

    Implementation

    The integration with Gradle is very easy, you just need the jcenter repository and the library:

    repositories {
        jcenter()
    }
    ...
    
    dependencies {
        compile 'com.davidecirillo.multichoicerecyclerview:multichoicerecyclerview:1.0.1'
    }
    

    Main steps for usage

    Add the MultiChoiceRecyclerView to your xml file

    <com.davidecirillo.multichoicesample.MultiChoiceRecyclerView
        android:id="@+id/multiChoiceRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    Instanciate you object and connect the view

    MultiChoiceRecyclerView mMultiChoiceRecyclerView = (MultiChoiceRecyclerView) findViewById(R.id.multiChoiceRecyclerView);
    

    Extend you adapter to the MultiChoiceAdapter and add it to the RecyclerView as per normal usage

    public class MyAdapter extends MultiChoiceAdapter<MyViewHolder> {
    
        public MyAdapter(ArrayList<String> stringList, Context context) {
            this.mList = stringList;
            this.mContext = context;
        }
    
        ...
    } 
    
    MyAdapter myAdapter = new MyAdapter(mList, getApplicationContext());
    mMultiChoiceRecyclerView.setAdapter(myAdapter);
    

    For more information and customisations: https://github.com/dvdciri/MultiChoiceRecyclerView

    0 讨论(0)
提交回复
热议问题