Android-RadioGroup+ScrollView 实现联动标签效果

开篇

新的项目中有一个很长的资料提交和资料查看页面,为了方便查看,上方加了 RadioGroup 分类标签,可以快速滑动的相应位置。
实现的效果和下面差不多,其实,蘑菇街的商品详情也是这样实现的。

在这里插入图片描述

实现思路

  1. RadioGroup + ScrollView 控件搭配实现

  2. RadioGroup 的 OnCheckedChangeListener 监听事件中拿到 RadioButton 对应的内容 Y 坐标,通过 scrollTo(0,Y)或者 smoothScrollTo(0,Y) 控制 ScrollView 的滑动。

  3. ScrollView 的 onScrollChanged 方法中通过 Y 值判断范围,来确定选中哪个 RadioButton 。

始料未及的小问题 & 解决方法

上面的步骤是不是看起来是不是超级简单,然而事实证明,too young to naive !

1.OnCheckedChangeListener 和 onScrollChanged 会互相触发呐呐呐,下滑时还好,上滑的时候,标签直接会连续选中到第一个。

2.被上滑时不受控制的 ScrollView 折磨得几乎要疯的我,发现是 RadioGroup 的锅,这货的 onCheckedChanged 一次触发会调用多次。

OnCheckedChangeListener 和 onScrollChanged 会互相触发

实话说,这是非常正常的表现,毕竟是需要相互联动的两个控件,就是联动的时机有误,需要我们来手动控制一下。

现状:
点击 RadioGroup ,ScrollView 滑动到固定位置,上滑不会有问题,下滑时由于判断条件不同,ScrollView 滑动到固定位置时会触发 RadioGroup 的监听事件。

需求:
RadioGroup 触发的时候,,ScrollView 中对 RadioGroup 就不要触发。
ScrollView 联动触发 RadioGroup 的时候,RadioGroup 对 ScrollView 的联动不要触发。

简单来说,就是双向同时联动改成双向不同时联动。

修改方法:

1.添加两个变量:

boolean isScrollFlag = false ;
boolean isRadioFlag = false;

2.RadioGroup 的 onCheckedChanged 中的判断:

//拦截 scrollView 中的联动触发
if(isScrollFlag){
    isScrollFlag = isRadioFlag = false;
    return;
}

3.ScrollView 的 onScrollChanged 中的判断:

//拦截 radioGroup 选中的联动触发
if(isRadioFlag ){
    Log.d(TAG, "onScrollChanged: 拦截");
    isRadioFlag = isScrollFlag = false;

    return;
}

RadioGroup 调用check()方法 onCheckedChanged 一次触发多次调用的问题。

多次触发是 check() 中多次调用了 setCheckedId() 方法,而 setCheckedId() 里面又有多次调用 onCheckedChanged 。以上这句话的具体细节请自行查看相关源码。这里放上我的解决方法:

在 RadioGroup 的 onCheckedChanged 方法里加入如下代码:

mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
     @Override
     public void onCheckedChanged(RadioGroup group, int checkedId) {

         //防止onCheckedChanged 被调用多次
         View viewById = mRadioGroup.findViewById(checkedId);
         if (!viewById.isPressed()){
             Log.w(TAG, "onCheckedChanged: 阻止");
             return;
         }

         //...
       }
});

最后

本来想按照实现步骤一步步附上上对应的代码的,后来想想也不是很有必要,还是思路说清楚比较重要,最后附上完整代码链接。

完整代码在这里

发现一个待改进的问题,就是 scrollView 调用 smoothScrollTo(0,Y) 方法其实也是会多次触发 onScrollChanged()。虽然最后实现了效果,但是总是有点不对的,这个问题后面会再优化。

技术粗浅,如果有不对的地方,还请留言告知。


欢迎关注个人微信公众号「浅浅同学的开发笔记」,最新的博客,好玩的事情,都会在上面分享,期待与你共同成长。

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中,radiogroup的值可以通过以下方式获取: 1. 在布局文件中定义radiogroup时,可以为每个radiobutton设置一个id,然后在代码中通过findViewById()方法获取radiogroup对象,再通过getCheckedRadioButtonId()方法获取选中的radiobutton的id值。 例如: ```xml <RadioGroup android:id="@+id/radioGroup" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:id="@+id/radioButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Option 1" /> <RadioButton android:id="@+id/radioButton2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Option 2" /> <RadioButton android:id="@+id/radioButton3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Option 3" /> </RadioGroup> ``` 在代码中获取选中的radiobutton的id值: ```java RadioGroup radioGroup = findViewById(R.id.radioGroup); int selectedId = radioGroup.getCheckedRadioButtonId(); ``` 2. 也可以通过监听radiogroup选中状态来获取选中的radiobutton的值。 例如: ```java RadioGroup radioGroup = findViewById(R.id.radioGroup); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.radioButton1: // do something when option 1 is selected break; case R.id.radioButton2: // do something when option 2 is selected break; case R.id.radioButton3: // do something when option 3 is selected break; } } }); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值