美文网首页
Android RadioButton多行多列实现

Android RadioButton多行多列实现

作者: vesselzhang | 来源:发表于2017-10-17 10:51 被阅读0次

    最近在做项目的时候,设计小哥给到了如下需求:


    image.png

    看上去简单,xml写起来:

    <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <RadioButton
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="xxx" />
    
                    <RadioButton
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="xxx" />
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <RadioButton
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="xxx" />
    
                    <RadioButton
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="xxx" />
                </LinearLayout>
            </RadioGroup>
    

    然而悲伤的事情来了,RadioGroup失去了它的单选功能,有且只有同一行的RadioButton可以单选。这是怎么回事呢?看看RadioGroup源码:

        @Override
        public void addView(View child, int index, ViewGroup.LayoutParams params) {
            if (child instanceof RadioButton) {
                final RadioButton button = (RadioButton) child;
                if (button.isChecked()) {
                    mProtectFromCheckedChange = true;
                    if (mCheckedId != -1) {
                        setCheckedStateForView(mCheckedId, false);
                    }
                    mProtectFromCheckedChange = false;
                    setCheckedId(button.getId());
                }
            }
    
            super.addView(child, index, params);
        }
    

    这里仅仅判断了RadioButton!这限制就大了。

    当然解决方案也有多种:
    1.重写RadioGroup,在子View的操作上做文章。
    2.布局不变,动态的判断点击的RadioButton来清除其它的RadioGroup。
    3.使用RecyclerView来刷新整个列表

    我使用到的方法就是第三种,原因在于RecyclerView通过GridLayoutManager可以动态的变换整个列表的列数(非常实用),而且不用去写RadioGroup里面的布局结构,只需要根据传入的List即可轻松实现。
    话不多说,快看看代码吧
    布局:

    <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/radio_rv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
    </RadioGroup>
    

    是不是很简单啊

    RecyclerView rv = UiUtils.find(view, R.id.radio_rv);
    RadioRecycleAdapter radioAdapter = new RadioRecycleAdapter(mApplication, valueList);
    radioAdapter.setOnItemClickListener((holder, pos) -> {
        //TODO
    });
    rv.setLayoutManager(new GridLayoutManager(mApplication, 2));
    rv.setAdapter(radioAdapter);
    rv.addItemDecoration(new SpaceItemDecoration(49));
    
    public class RadioRecycleAdapter extends RecyclerView.Adapter<RadioRecycleAdapter.MyViewHolder> {
    
        private Context mContext;
        private List<String> mDatas;
        private int mSelectedItem = -1;
    
        public interface OnItemClickListener {
            void onItemClick(String holder, int pos);
        }
    
        private OnItemClickListener mListener;
    
        public void setOnItemClickListener(OnItemClickListener listener) {
            this.mListener = listener;
        }
    
        public RadioRecycleAdapter(Context mContext, List<String> datas) {
            this.mContext = mContext;
            this.mDatas = datas;
        }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_radio, parent, false));
            return holder;
        }
    
        @Override
        public void onBindViewHolder(final MyViewHolder holder, final int position) {
            holder.radioButton.setText(mDatas.get(position));
            holder.radioButton.setChecked(position == mSelectedItem);
            holder.radioButton.setTag(position);
            holder.radioButton.setOnClickListener(v -> {
                mSelectedItem = (int) v.getTag();
                notifyItemRangeChanged(0, mDatas.size());
                if (mListener != null) {
                    mListener.onItemClick(mDatas.get(holder.getLayoutPosition()), holder.getLayoutPosition());
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return mDatas.size();
        }
    
        public void addData(String data, int pos) {
            mDatas.add(pos, data);
            notifyItemInserted(pos);
        }
    
        public void removeData(int pos) {
            mDatas.remove(pos);
    
            notifyDataSetChanged();
            notifyItemRemoved(pos);
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
            RadioButton radioButton;
    
            public MyViewHolder(View itemView) {
                super(itemView);
    
                radioButton = (RadioButton) itemView.findViewById(R.id.radio_rb);
            }
        }
    }
    

    效果可以看最上面的图片。Over

    相关文章

      网友评论

          本文标题:Android RadioButton多行多列实现

          本文链接:https://www.haomeiwen.com/subject/fsnruxtx.html