频道栏目
首页 > 程序开发 > 移动开发 > Android > 正文
Android多点触控RadioGroup结合Fragment实现底部Tab
2018-07-04 13:39:12      个评论    来源:huch的博客  
收藏   我要投稿

Android底部导航栏(底部Tab)是一个Android程序员入门必须会实现的一个功能点,在Material Design(基于Android 5.0 API level 21)设计出来之前大家实现底部Tab通常会用FragmentTabHost或RadioGroup方式。而在有了

Android Support Library (com.android.support:design:xx.x.x)

后就可以使用官方 提供的TabLayout 或 BottomNavigationView 控件了。

当然这篇文章不是去讲上面提到的4种方式怎么去实现的,而是分析一下早期使用RadioGroup方式实现时的一些疑问,正事一下的自己的判断。

当时采用 RadioGroup + RadioButton组合使用实现单选功能,就想到了一个case:当用户同时点击多个Tab的时候,RadioGroup控件的OnCheckedChangeListener监听事件会不会响应多次,当时的我只是想当然地认为官方推出的这种组合应该考虑到了这个case了吧,会做处理地只会响应一次事件,自己也没去加Log验证了,就这样放任过去了……

以至于后面在再次实现底部Tab的时候, 当内心有想法采用自定义View实现Tab的(因为Icon可以高度定制),但是一想到已有成熟轮子了自己也就不去费时间弄了。

做了这么多年后,心态也会逐步发生改变,从知其然到知其然知其所以然再到知其所以然知其所必然。

为了验证问题,就简单做了下实验:

一个水平的线性布局包含4个TextView控件,分别注册了点击事件itemClick
<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="horizontal">

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:onClick="itemClick"
       android:padding="10dp"
       android:text="测试1" />
   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginLeft="40dp"
       android:gravity="center"
       android:onClick="itemClick"
       android:padding="10dp"
       android:text="测试2" />
   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginLeft="40dp"
       android:layout_marginRight="40dp"
       android:gravity="center"
       android:onClick="itemClick"
       android:padding="10dp"
       android:text="测试3" />
   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:onClick="itemClick"
       android:padding="10dp"
       android:text="测试4" />
</LinearLayout>

public void itemClick(View view){
        for(int i=0;i<200;i++){
           LogUtils.loge("itemClick",i+"--"+((TextView)view).getText().toString());
        }
        LogUtils.loge("itemClick结束-",((TextView)view).getText().toString());
    }

大家觉得在我们用手同时点击2个TextView控件的时候,点击事件的回调是同时进行还是先后执行呢?
Touch事件是同时接收到的,但我们再先想一下点击事件的回调是触发在哪个线程呢?。没错事件的回调是UI主线程,所以同时点击2个控件虽然都会有响应,但是点击事件触发是存在先后的,为了证明此点特意加了一个for循环延时,日志显示当同时点击2个控件时,Onclick事件的回调的确是存在先后的。
不过虽然是先后执行,但是也需要改进的,因为这属于回调了一次事件属于浪费,而浪费是可耻的哈。

后面也把log加在了RadioGroup控件的OnCheckedChangeListener监听事件上,发现竟然也先后执行了多次,后面去看了下源码,发现也是没做处理跟我们写自定义Tab是差不多的逻辑控制。

那么说到这里该怎么简单快速解决呢?那就是利用Android本身的多点触控功能:
只要在xml文件中的父容器加入这样一行代码即可:
android:splitMotionEvents=”false”或者动态代码.setMotionEventSplittingEnabled()
如在上面的LinearLayout中加入这行话,表示每一次只能点击LinearLayout其中的一个元素,点击了其他的元素是无效的。

如果一次性应用到Application、Activity的话,可以通过自定义主题的方式来关掉多点触摸功能
在windows中禁止split touch events:
<style name="NoSplitMotionEvents" parent="Theme.xxx">
     <item name="android:windowEnableSplitTouch">false</item>
     <item name="android:splitMotionEvents">false</item>
         ...      
</style>

所以咱们也只需在RadioGroup的xml上添加android:splitMotionEvents=”false”即可解决问题

点击复制链接 与好友分享!回本站首页
上一篇:Android Studio依赖方式实例讲解
下一篇:MVP模式实现Android的简单购物车(代码教程)
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站