最近为公司开发移动app,看到app的主页面就四个选项卡加对应的页面,但是代码写复杂无比,很难维护,鉴于此想用最少的代码实现其功能,废话不多说,先上效果图。

实现思路

从图我们基本猜到基本思路如下

  1. 底部选项卡可以使用3个RadioButton组成,并绑定相关的监听器以监听tab切换。
  2. 选项卡的上面的部分为一个容器(FrameLayout)以存取3个fragment,可以在tab绑定的监听器中去控制fragment的显示。

布局文件

先看主页面的布局文件R.layout.activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><RadioGroupandroid:id="@+id/ll_rbtn_contain"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:gravity="center"android:orientation="horizontal" ><RadioButtonandroid:id="@+id/rb_first"style="@style/tab_style"android:drawableTop="@drawable/tab_first_background"android:text="first"android:textColor="@color/radio_colors" /><RadioButtonandroid:id="@+id/rb_second"style="@style/tab_style"android:drawableTop="@drawable/tab_second_background"android:text="second"android:textColor="@color/radio_colors" /><RadioButtonandroid:id="@+id/rb_thrid"style="@style/tab_style"android:drawableTop="@drawable/tab_third_background"android:text="thrid"android:textColor="@color/radio_colors" /></RadioGroup><FrameLayoutandroid:id="@+id/fl_contain"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/ll_rbtn_contain"android:layout_alignParentTop="true" ></FrameLayout></RelativeLayout>

根视图为相对布局以控制RadioGroup在底部,FrameLayout在RadioGroup的上面


设置选项卡Style

每个RadioButton都设置了统一的tab_style

<!-- 底部Tab按钮样式 -->
<style name="tab_style"><item name="android:textSize">12sp</item><item name="android:gravity">center</item><item name="android:background">@drawable/home_btn_bg</item><item name="android:layout_width">fill_parent</item><item name="android:layout_height">wrap_content</item><item name="android:button">@null</item><item name="android:paddingTop">2dp</item><item name="android:singleLine">true</item><item name="android:layout_weight">1.0</item>
</style>

设置选项卡icon的背景

每个radioButton都设置了android:drawableTop属性,只要创建三个drawable文件即可 eg :tab_first_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/first_pressed" android:state_pressed="true"/><item android:drawable="@drawable/first_pressed" android:state_checked="true"/><item android:drawable="@drawable/first_normal"/>
</selector>

设置选项卡title的背景

除了选显卡对应的icon要改变外,其对应的title的字体颜色也要随之改变。注意要在res下创建color文件夹并将颜色状态配置文件放在此文件夹下。eg:radio_colors.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true" android:color="@color/orange_color"/><item android:state_checked="true" android:color="@color/orange_color"/><item android:color="#aaaaaa" />
</selector>

代码块

package com.example.tabapp;import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.RadioButton;public class MainActivity extends FragmentActivity implements OnCheckedChangeListener{//三个选项卡private RadioButton mRBtnFrist;private RadioButton mRBtnSecond;private RadioButton mRBtnThrid;//存放fragment对应的容器private FrameLayout mFragmentContain;private TabFragment mFirstFragment;private TabFragment mSecondFragment;private TabFragment mThirdFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mFragmentContain = (FrameLayout)findViewById(R.id.fl_contain);mRBtnFrist = (RadioButton)findViewById(R.id.rb_first);mRBtnSecond = (RadioButton)findViewById(R.id.rb_second);mRBtnThrid = (RadioButton)findViewById(R.id.rb_thrid);mRBtnThrid.setOnCheckedChangeListener(this);mRBtnThrid.performClick();//此处设置默认第三个选项卡对应的fragment显示mRBtnFrist.setOnCheckedChangeListener(this);mRBtnSecond.setOnCheckedChangeListener(this);}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (isChecked) {//用户当前浏览的选项卡int checkedWidgetId = buttonView.getId();mRBtnFrist.setChecked(checkedWidgetId == R.id.rb_first);mRBtnSecond.setChecked(checkedWidgetId == R.id.rb_second);mRBtnThrid.setChecked(checkedWidgetId == R.id.rb_thrid);showFragment(checkedWidgetId);}else {//此处记录了用户上次浏览的选项卡String unCheckFragmentTag = getTagById(buttonView.getId());TabFragment unCheckFragment = (TabFragment)getSupportFragmentManager().findFragmentByTag(unCheckFragmentTag);if(unCheckFragment != null){//隐藏上次显示到fragment,确保fragment不会重叠getSupportFragmentManager().beginTransaction().hide(unCheckFragment).commit();}}}/*** 显示对应的fragment* @param checkedRadioBtnId*/private void showFragment(int checkedRadioBtnId){String tag = getTagById(checkedRadioBtnId);TabFragment mainFragment = (TabFragment) getSupportFragmentManager().findFragmentByTag(tag);if(mainFragment == null){//如果没有找到对应的fragment则生成一个新的fragment,并添加到容器中TabFragment newFragment = new TabFragment(tag);getSupportFragmentManager().beginTransaction().add(R.id.fl_contain, newFragment, tag).commit();}else {//如果找到了fragment则显示它getSupportFragmentManager().beginTransaction().show(mainFragment).commit();}}/*** 为三个fragment分别取三个不同到tag名* @param widgetId* @return*/private String getTagById(int widgetId){if(widgetId == R.id.rb_first){return "first";}else if(widgetId == R.id.rb_second){return "second";}else {return "thrid";}}
}

好了这样我们就基本实现了选显卡功能,代码注释写的很详细了,相信大家肯定明白,我就不加阐述了,good luck!

源码下载

Android 使用RadioButton+Fragment构建Tab相关推荐

  1. Android典型界面设计(4)——使用ActionBar+Fragment实现tab切换

    一.问题描述 之前我们使用ViewPager+Fragment区域内头部导航,在Android 3.0之后Google增加了新的ActionBar,可方便的实现屏幕Head部区域的 设计如返回键.标题 ...

  2. Android官方开发文档Training系列课程中文版:使用Fragment构建动态UI之与其它Fragment通信

    原文地址:http://android.xsoftlab.net/training/basics/fragments/communicating.html 为了可以重复使用Fragment UI组件, ...

  3. Android官方开发文档Training系列课程中文版:使用Fragment构建动态UI之Fragment创建

    原文地址:http://android.xsoftlab.net/training/basics/fragments/index.html 导言 为了在Android中创建动态的多面板用户界面,你需要 ...

  4. 使用Fragment实现Tab效果

    在上一篇中,我们将了使用ViewPager实现Tab效果.如果没有阅读过,可以点击下面的地址: http://www.cnblogs.com/fuly550871915/p/4849893.html ...

  5. android 弹出fragment,Android中ViewPager获取当前显示的Fragment

    前言 在项目中,有时会用到在ViewPager中显示同样类型的Fragment,同时这样的Fragment的个数是动态的,但是PagerAdapter没有给我们提供getCurrentFragment ...

  6. 【Android】保存Fragment切换状态

    [Android]保存Fragment切换状态 前言 一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法. 声明 欢迎转载,但请保留文章 ...

  7. android 底部tab效果,Android 仿微信底部渐变Tab效果

    先来看一下效果图 除了第三个的发现Tab有所差别外,其他的基本还原了微信的底部Tab渐变效果 每个Tab都是一个自定义View,根据ImageView的tint属性来实现颜色渐变效果,tint属性的使 ...

  8. 低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航

    Tab经常和Fragment结合使用,这一讲我们用3种方式来实现这种快捷导航. 0.重要的两个监听器 MyTabListener,这个我们之前已经接触过了 package com.kale.actio ...

  9. Android studio包含四个tab微信页面设计

    Android studio包含四个tab微信页面设计 1.导入图标 新建一个project,然后将所需八个图标导入至app/res/drawable目录下任意的ic_launcher_xxxxx(复 ...

最新文章

  1. IPv6改造三步曲——Vecloud
  2. Spring-依赖注入
  3. 父窗体与子窗体之间的调用-使用模态窗体之间传递多个值
  4. 微信小程序+ColorUI
  5. win7安装wildfly8.1
  6. 专访Riverbed CEO:私有化和出售业务瘦身后的Riverbed更专注
  7. 上下协同,用友IPD的研发管理之道(下)
  8. Linux-5.10源代码之网络系统简介:
  9. python学习--统计序列中元素出现的频度(次数)
  10. 游戏测试工程师的光荣与梦想(一)-百炼成钢
  11. 谷歌地图JavaScript API第3版 地理编码服务
  12. java二维数组添加数据_Java自学路线图
  13. 关于一些C语言代码优化的方法,我慷慨解囊了大家酌情收藏
  14. 服务器中使用Top命令后,参数解释
  15. 干货:嵌入式系统设计开发大全!(万字总结)-道合顺大数据infinigo
  16. Centos7镜像下载步骤
  17. 中国科学院843遥感概论-目录
  18. 向大家推荐一款功能强大且免费的杀毒软件:avast! 4 Professional Edition
  19. CFA黑料揭秘之CFA持证人年薪
  20. ios 图片裁剪框架_iOS图片裁剪器 – RSKImageCropper

热门文章

  1. ant如何形成时间轴和图库_高中历史时间轴来了(电子高清版),最新最完整的复习时间线整理,这里都有!...
  2. 用kali的Meterpreter控制win10,可以偷看你的电脑的所有数据
  3. 节省显存新思路,在PyTorch里使用2 bit激活压缩训练神经网络
  4. 我们可以无损放大一个Transformer模型吗?
  5. Learning to Learn:图神经网络上的元学习
  6. 新的一年,想发有关对话系统的paper?快关注时下最大热点:智能化与个性化...
  7. web公选课第三节2020.5.18
  8. HDU 6186 CS Course
  9. flask与js交互的示例代码_dapr实战(1):dapr locally环境的搭建和部署官方的Hello world示例...
  10. 屏的像素与传输速率_柔性半导体新突破:传输速度已足够驱动OLED像素