RadioButton 搭配RadioGroup实现多行多列 单选

前言

平时很多项目中都会用到RadioButton搭配RadioGroup来实现单选,但是有时候在UI上会经常出现多排的情况,这种情况使用RadioGroup搭配RadioButton是无法实现单选情况

为什么RadioGroup搭配RadioButton是无法实现单选

主要是RadioGroup造成

public class RadioGroup extends LinearLayout 

RadioGroup 继承 LinearLayout 所有保留了LinearLayout的特性

初始化时候通过监听的方式来添加对RadioButton的监听

    private void init() {
        mChildOnCheckedChangeListener = new CheckedStateTracker();
        mPassThroughListener = new PassThroughHierarchyChangeListener();
        super.setOnHierarchyChangeListener(mPassThroughListener);
    }

这里就是就是原因,如果RadioGroup包裹的不是RadioButton将不会添加监听

        public void onChildViewAdded(View parent, View child) {
            if (parent == RadioGroup.this && child instanceof RadioButton) {
                int id = child.getId();
                // generates an id if it's missing
                if (id == View.NO_ID) {
                    id = View.generateViewId();
                    child.setId(id);
                }
                ((RadioButton) child).setOnCheckedChangeWidgetListener(
                        mChildOnCheckedChangeListener);
            }

            if (mOnHierarchyChangeListener != null) {
                mOnHierarchyChangeListener.onChildViewAdded(parent, child);
            }
        }

解决方式

1.采用其他方案

如 使用RecyclerView,自定义控件等,这里只简单提一下

2.自定义RadioGroup

通过重写的RadioGruop的方式来实现对RadioButton 的重新包裹,可以参考源码,不用继承LinearLayout,这样其子控件就可以随意乱摆了

3.包裹RadioGroup

代码如下

lass RadioGroupGroup : LinearLayoutCompat, RadioGroup.OnCheckedChangeListener{

    private var mOnCheckedChangeListener: OnCheckedChangeListener? = null

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    private val radioButtonMap = mutableMapOf<Int, RadioButton>()

    private val radioGroupMap = mutableMapOf<Int, RadioGroup>()



    override fun addView(child: View?, params: ViewGroup.LayoutParams?) {
        super.addView(child, params)
        if (child is RadioGroup) {
            child.setOnCheckedChangeListener(this)
            child.forEach {
                if (it is RadioButton) {
                    radioButtonMap[it.id] = it
                    radioGroupMap[it.id] = child
                }
            }
        }
    }


    interface OnCheckedChangeListener {
        /**
         *
         * Called when the checked radio button has changed. When the
         * selection is cleared, checkedId is -1.
         *
         * @param group the group in which the checked radio button has changed
         * @param checkedId the unique identifier of the newly checked radio button
         */
        fun onCheckedChanged(group: RadioGroup?, @IdRes checkedId: Int)
    }

   //记录最后一次点击的RadioGroup
   private var lastRadioGroup: RadioGroup? = null

    override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
        if (group == null || checkedId == -1) {
            return
        }
        if (radioButtonMap[checkedId]?.isChecked == true) {
            mOnCheckedChangeListener?.onCheckedChanged(group, checkedId)
            if (lastRadioGroup != group && lastRadioGroup!=null){
                lastRadioGroup!!.clearCheck()
            }
            lastRadioGroup = group
        }
    }


    fun check(@IdRes id: Int) {
        radioGroupMap[id]?.check(id)
    }

    fun setOnCheckedChangeListener(listener: OnCheckedChangeListener) {
        mOnCheckedChangeListener = listener
    }

当然这样会让布局的层次加重,不过代码简单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值