当前位置:首页 > 分类119 > 正文

radioGroup.check()执行了多次OnCheckedChangeListener()

摘要: radioGroup.check( 执行了多次OnCheckedChangeListener( 最佳答案53678位专家为你答疑...

radioGroup.check()执行了多次OnCheckedChangeListener()

最佳答案 53678位专家为你答疑解惑

radioGroup.check()执行了多次OnCheckedChangeListener()

问题:radioGroup.check(id)时,OnCheckedChangeListener被调用多次,2次3次都有-原因:radioGroup.check(id)的源码如下
    public void check(@IdRes int id) {        // don't even bother        if (id !=-1 && (id==mCheckedId)) {            return;        }        if (mCheckedId !=-1) {            setCheckedStateForView(mCheckedId, false);        }        if (id !=-1) {            setCheckedStateForView(id, true);        }        setCheckedId(id);    }

setCheckedStateForView(id, boolean)会调用setCheckedId(id)setCheckedId(id);源码如下

        if (mChecked !=checked) {            mCheckedFromResource=false;            mChecked=checked;            refreshDrawableState();            notifyViewAccessibilityStateChangedIfNeeded(                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);            // Avoid infinite recursions if setChecked() is called from a listener            if (mBroadcasting) {                return;            }            mBroadcasting=true;            if (mOnCheckedChangeListener !=null) {                //-----------注意这里调用了监听-----------------                mOnCheckedChangeListener.onCheckedChanged(this, mChecked);              }

可以看出,原选中的radioButton有值,会被调一次mOnCheckedChangeListener,新选中的也会调一次,最后又会调一次。所以会出现调用2次或3次的情况。

解决:方法1.将radioGroup.check() 替换成radioButton.setChecked(true)方法2. 自己维护一个mCheckId,若监听回调这个checkIdmCheckId一致则不处理。若checkIdview选中状态为false也不处理。

安卓干货铺-Android底部导航总结

底部导航方式

BottomNavigationBar

TabLayout

RadioGroup

LinearLayout + TextView

checkBox

这里只讲解前三种实现方式。

一.BottomNavigationBar+viewPager

先上效果图:

1.使用方法:

BottomNavigationBar源码下载地址:

https://github.com/Ashok-Varma/BottomNavigation

(1).添加依赖

compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.2'

(2).布局

 <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"></android.support.v4.view.ViewPager><com.ashokvarma.bottomnavigation.BottomNavigationBar android:id="@+id/bottom_navigation_bar" android:layout_gravity="bottom" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content"></com.ashokvarma.bottomnavigation.BottomNavigationBar>

(3).主要代码

 bottom_navigation_bar.setMode(BottomNavigationBar.MODE_SHIFTING) .setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);// bottom_navigation_bar //值得一提,模式跟背景的设置都要在添加tab前面,不然不会有效果。// .setActiveColor("#ffffff")//选中颜色 图标和文字// .setInActiveColor("#8e8e8e")//默认未选择颜色// .setBarBackgroundColor("#00796B");//默认背景色 bottom_navigation_bar .addItem(new BottomNavigationItem(R.mipmap.ic_favorite_white_24dp,"Like").setActiveColorResource(R.color.orange)) .addItem(new BottomNavigationItem(R.mipmap.ic_home_white_24dp,"Home").setActiveColorResource(R.color.teal)) .addItem(new BottomNavigationItem(R.mipmap.ic_music_note_white_24dp,"Music").setActiveColorResource(R.color.blue)) .addItem(new BottomNavigationItem(R.mipmap.ic_tv_white_24dp,"TV").setActiveColorResource(R.color.brown)) .setFirstSelectedPosition(0)//设置默认选择的按钮 .initialise();//所有的设置需在调用该方法前完成 viewPager.setCurrentItem(0); bottom_navigation_bar //设置lab点击事件 .setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener() { @Override public void onTabSelected(int position) { viewPager.setCurrentItem(position); } @Override public void onTabUnselected(int position) { } @Override public void onTabReselected(int position) { } });

2.部分属性解析

Mode属性:

对应的代码为:

bottom_navigation_bar.setMode(BottomNavigationBar.MODE_SHIFTING);

这个属性有两种可选的值,MODE_FIXED和MODE_SHIFTING。

MODE_FIXED:选中的Item会稍大于未选中的Item,无论Item是否选中,都会显示文字和图标。

MODE_SHIFTING:选中的Item明显大于未选中的Item,未选中的Item只显示图标

上面的效果图就是MODE_SHIFTING的效果,被选中的item明显扩大,至于MODE_FIXED属性我就不做演示了。

BackgroundStyle属性:

对应的代码为:

bottom_navigation_bar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);

这个属性有两个可选的值:

BACKGROUND_STYLE_RIPPLE

BACKGROUND_STYLE_STATIC

上面的效果图是BackgroundStyle的属性是BACKGROUND_STYLE_RIPPLE ,下面展示的是BACKGROUND_STYLE_STATIC 属性的:

Item角标设置

通过BottomNavigationItem的setBadgeItem方法,可以给每个Item设置一个独立的角标,对于角标支持设置它的背景、文案、文案颜色以及在选中时是否隐藏角标:

BadgeItem badgeItem=new BadgeItem()  .setBackgroundColorResource(android.R.color.holo_red_dark) //设置角标背景色  .setText("5") //设置角标的文字  .setTextColorResource(android.R.color.white) //设置角标文字颜色 .setHideOnSelect(true); //在选中时是否隐藏角标 mBottomNavigationBar.addItem(new BottomNavigationItem(R.drawable.ic_5, "Item 5") .setActiveColorResource(android.R.color.holo_orange_dark)  .setBadgeItem(badgeItem));

其他属性

 .setActiveColor("#ffffff")//选中颜色 图标和文字 .setInActiveColor("#8e8e8e")//默认未选择颜色 .setBarBackgroundColor("#00796B");//默认背景色 .setFirstSelectedPosition(0)//设置默认选择的按钮 .initialise();//所有的设置需在调用该方法前完成

还有一些其他的属性,这里就不一一列出了。

二.RadioGroup+ViewPager

核心代码:

radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId){ case R.id.rb_Monitor: viewPager.setCurrentItem(0); break; case R.id.rb_Notice: viewPager.setCurrentItem(1); break; case R.id.rb_line: viewPager.setCurrentItem(2); break; case R.id.rb_date: viewPager.setCurrentItem(3); break; } }});radioGroup.check(R.id.rb_Monitor);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { switch (position){ case 0: radioGroup.check(R.id.rb_Monitor); break; case 1: radioGroup.check(R.id.rb_Notice); break; case 2: radioGroup.check(R.id.rb_line); break; case 3: radioGroup.check(R.id.rb_date); break; } }

三.TabLayout+viewPager

TabLayout相信大家都很清楚吧,TabLayout提供了一个水平的布局用来展示Tabs。一般不会用在底部导航,这里只是总结这种方式。

代码就不贴出来了,如果有疑问直接关注私信我!

发表评论