【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/4463931.html

【正文】

实现APP首页底部Tab的切换已经见过四五种方式了,先来看运行的效果图吧:

今天我们就用RadioGroup的方法来实现以下。

【开发环境】

物理机版本:win 7旗舰版(64位)

IDE版本:Android Studio 1.2 preview

工程文件结构:(本文最后有源码)

  • HomeActivity.java:整个首页的界面
  • 四个Fragment.java:对应的四个Fragment界面
  • drawable文件夹中是对应tab和文字切换的状态
  • 剩下的xml文件就是对应的Activity和Fragment的布局文件了。

一、布局文件:

(1)activity_home.xml:HomeActivity的布局文件

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity"> <!--tab上方的显示区域-->
<FrameLayout
android:id="@+id/mHomeContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/mHomeRadioGroup"> </FrameLayout> <!--底下的四个tab-->
<RadioGroup
android:id="@+id/mHomeRadioGroup"
android:layout_width="match_parent"
android:layout_height="56dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:background="@color/tab_bg" > <RadioButton
android:id="@+id/mHomeHomeRb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:text="@string/home_home"
android:textColor="@drawable/selector_tab_text_color"
android:background="@color/tab_bg"
android:drawableTop="@drawable/selector_tab_home"
/> <RadioButton
android:id="@+id/mHomeFindRb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:text="@string/home_find"
android:textColor="@drawable/selector_tab_text_color"
android:background="@color/tab_bg"
android:drawableTop="@drawable/selector_tab_find"
/> <RadioButton
android:id="@+id/mHomeSearchRb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:text="@string/home_search"
android:textColor="@drawable/selector_tab_text_color"
android:background="@color/tab_bg"
android:drawableTop="@drawable/selector_tab_search"
/> <RadioButton
android:id="@+id/mHomeProfileRb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:text="@string/home_profile"
android:textColor="@drawable/selector_tab_text_color"
android:background="@color/tab_bg"
android:drawableTop="@drawable/selector_tab_profile"
android:checked="true"
/>
</RadioGroup>
</RelativeLayout>

代码有点多,无非就是一个FrameLayout对应的是tab上方的显示区域,然后四个RadioButton凑成一组单选按钮放在RadioGroup当中。

13行:能够保证FrameLayout占据除开Tab之后的剩下的全部空间。

76行:android:checked="true"这个很重要,稍后在java代码中讲。

RadioButton的属性有点多,我们选取就选取第一个RadioButton进行讲解,上面的第一个RadioButton的属性摘抄如下:

         <RadioButton
android:id="@+id/mHomeHomeRb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:text="@string/home_home"
android:textColor="@drawable/selector_tab_text_color"
android:background="@color/tab_bg"
android:drawableTop="@drawable/selector_tab_home"
/>

上方代码的解释如下:

05行:weight为1,并且width为0dp,是保证四个tab能均分宽度。

06行:去掉RadioButton的样式,也就是去掉那个小图标,然后radiobutton就只剩下文字了。

07行:让里面的内容居中

08行:显示的文字

10行:设置这个tab的背景色和整个radioGroup的背景色一样,不过,也可以删掉(删掉之后,在我的小米手机手机上的排版会有问题)

10行:在这个tab的上面添加对应的icon图标(很重要,就是有了这个属性,每个tab的图标才会不一样哦)。

(2)fragment_home.xml:fragment的布局文件

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HomeFragment"
android:textSize="20sp"/> </LinearLayout>

其他三个fragment的布局文件都一样,代码就不贴出来了,本文最后有源码下载。

(3)selector_tab_home.xml:tab被选中时对应icon的状态

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

06行是默认的状态。

其他三个tab的状态都差不多,代码就不贴出来了,本文最后有源码下载。

(4)selector_tab_text_color.xml:tab中的文字被选中时的状态

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/white" android:state_pressed="false" android:state_selected="true" />
<item android:color="@color/white" android:state_checked="true" android:state_pressed="false" />
<item android:color="@color/black" /> </selector>

06行:默认的文字颜色是黑色,被切换时是白色。

二、Java代码:

(1)HomeActivity.java:

 package com.smyhvae.radiogrouptabdemo;

 import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup; import com.smyhvae.radiogrouptabdemo.fragment.FindFagment;
import com.smyhvae.radiogrouptabdemo.fragment.HomeFagment;
import com.smyhvae.radiogrouptabdemo.fragment.ProfileFagment;
import com.smyhvae.radiogrouptabdemo.fragment.SearchFagment; /**
* Created by smyhvae on 2015/4/28.
*
*/ public class HomeActivity extends FragmentActivity {
private FrameLayout mHomeContent;
private RadioGroup mHomeRadioGroup;
private RadioButton mHomeHomeRb;
private RadioButton mHomeFindRb;
private RadioButton mHomeSearchRb;
private RadioButton mHomeProfileRb; static final int NUM_ITEMS = 4;//一共四个fragment @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_home);
initView();
initData();
} protected void initView() {
mHomeContent = (FrameLayout) findViewById(R.id.mHomeContent); //tab上方的区域
mHomeRadioGroup = (RadioGroup) findViewById(R.id.mHomeRadioGroup); //底部的四个tab
mHomeHomeRb = (RadioButton) findViewById(R.id.mHomeHomeRb);
mHomeFindRb = (RadioButton) findViewById(R.id.mHomeFindRb);
mHomeSearchRb = (RadioButton) findViewById(R.id.mHomeSearchRb);
mHomeProfileRb = (RadioButton) findViewById(R.id.mHomeProfileRb); //监听事件:为底部的RadioGroup绑定状态改变的监听事件
mHomeRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int index = 0;
switch (checkedId) {
case R.id.mHomeHomeRb:
index = 0;
break;
case R.id.mHomeFindRb:
index = 1;
break;
case R.id.mHomeSearchRb:
index = 2;
break;
case R.id.mHomeProfileRb:
index = 3;
break;
}
//通过fragments这个adapter还有index来替换帧布局中的内容
Fragment fragment = (Fragment) fragments.instantiateItem(mHomeContent, index);
//一开始将帧布局中 的内容设置为第一个
fragments.setPrimaryItem(mHomeContent, 0, fragment);
fragments.finishUpdate(mHomeContent); }
});
} //第一次启动时,我们让mHomeHomeRb这个radiobutton处于选中状态。
// 当然了,在这之前,先要在布局文件中设置其他的某一个radiobutton(只要不是mHomeHomeRb就行)
// 的属性为android:checked="true",才会出发下面的这个check方法切换到mHomeHomeRb
@Override
protected void onStart() {
super.onStart();
mHomeRadioGroup.check(R.id.mHomeHomeRb);
} //用adapter来管理四个Fragment界面的变化。注意,我这里用的Fragment都是v4包里面的
FragmentStatePagerAdapter fragments = new FragmentStatePagerAdapter(getSupportFragmentManager()) { @Override
public int getCount() {
return NUM_ITEMS;//一共有四个Fragment
} //进行Fragment的初始化
@Override
public Fragment getItem(int i) {
Fragment fragment = null;
switch (i) {
case 0://首页
fragment = new HomeFagment();
break;
case 1://发现
fragment = new FindFagment();
break; case 2://搜索
fragment = new SearchFagment();
break; case 3://我的
fragment = new ProfileFagment();
break;
default:
new HomeFagment();
break;
} return fragment;
}
}; protected void initData() { } }

代码注释已经很详细了。

尤其要注意的是第80行的注释,为了让app第一次启动时,默认就让第一个tab处于选中状态,我们现在activity_home.xml(76行)中让剩下的随便哪个radioButton的属性为checked,然后再重写上方java代码中的onStart方法(86行)。

(2)HomeFragment.java:

 package com.smyhvae.radiogrouptabdemo.fragment;

 import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import com.smyhvae.radiogrouptabdemo.R; /**
* Created by smyh on 2015/4/28.
*/
public class HomeFagment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_home, null);
return view;
} //重写setMenuVisibility方法,不然会出现叠层的现象
@Override
public void setMenuVisibility(boolean menuVisibile) {
super.setMenuVisibility(menuVisibile);
if (this.getView() != null) {
this.getView().setVisibility(menuVisibile ? View.VISIBLE : View.GONE);
}
} }

剩下三个Fragment的java代码是一样的,就不贴出来了,详见本文最后的源码。

【工程文件】

2015-04-28-RadioGroupTabDemo

Android自定义控件----RadioGroup实现APP首页底部Tab的切换的更多相关文章

  1. Android之RadioGroup+ViewPager制作的底部导航栏

    在日常开发中我们常常会用到类似微信或者QQ的底部导航.实现这样的效果有多种,今天就为大家介绍一种实现简单,可控性好的底部导航的实现方法. 首先创建activity_main.xml布局文件,里面主要由 ...

  2. Fragment实现底部Tab,切换可保存状态

    activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android& ...

  3. react native底部tab栏切换

    1.安装tab栏插件 npm i react-native-tab-navigator --save 2.引入对应的组件和tab插件 import { Platform, StyleSheet, Te ...

  4. Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...

  5. Android典型界面设计——FragmentTabHost+Fragment实现底部tab切换

    一.问题描述 在上次博文中,我们使用RadioGroup+ViewPage+Fragmen实现了顶部滑动导航(查看文章:http://www.cnblogs.com/jerehedu/p/460759 ...

  6. Android 自定义控件之app标题栏的封装

    在app的开发中,每一个页面都有上面的标题栏,总不能在开发的过程中没个界面都写一个标题栏的布局,所以为了开发的方便,将该标题栏进行的封装,以后在实际的开发工作中,也可以将该封装好的标题栏控件直接拿来使 ...

  7. 使用hubuild,mui开发微信app—首页(一)

    写在前面 本系列文章我将介绍一下从零开始利用hubuild,mui实现微信app的开发,该系列是个人学习记录,所以在每篇文章中,都是从怎么去实现开始讲解,然后再把实例中涉及知识点做一个概述. 创建一个 ...

  8. 界面底部Tab实现

    现在基本上大部分的手机APP都要实现底部Tab,底部实现Tab的实现方式有很多种,那么有没有好的实现方式呢? 今天我将使用一个开源插件来实现底部Tab 参考自zhangli_的博客:http://bl ...

  9. [Android] Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单

    Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单 利用FragmentTabHost实现底部菜单,在该底部菜单中,包括了4个TabSpec,每个TabS ...

随机推荐

  1. Linux C 静态库(.a) 与 动态库(.so) 的详解

    库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1.静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较 ...

  2. C和指针 第八章 习题

    8.5矩阵运算,A是一个x行,y列矩阵,B是y行z列矩阵,把A和B相乘,结果是另外一个x行z列矩阵,每个位置的值由下公式决定,编写函数: #include <stdio.h> void m ...

  3. 2.1WebApi的路由

    这篇文章描述 ASP.NET Web API如何将 HTTP 请求通过路由去访问控制器. 如果你熟悉 ASP.NET MVC,Web API 路由是非常类似于 MVC 路由.主要的区别是 Web AP ...

  4. mapReduce编程之Recommender System

    1 协同过滤算法 协同过滤算法是现在推荐系统的一种常用算法.分为user-CF和item-CF. 本文的电影推荐系统使用的是item-CF,主要是由于用户数远远大于电影数,构建矩阵的代价更小:另外,电 ...

  5. 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.2)

    欢迎加入qq群551278936讨论krpano技术以及获取最新软件.   该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...

  6. InnoDB全文索引:N-gram Parser【转】

    本文来自:http://mysqlserverteam.com/innodb%E5%85%A8%E6%96%87%E7%B4%A2%E5%BC%95%EF%BC%9An-gram-parser/ In ...

  7. seajs和requirejs

    一.seajs 1. 使用seajs的一般步骤 a)在主页面引入sea.js b)写模块 c)在主页面使用模块 2.模块的写法 math.js define(function(require, exp ...

  8. October 23rd Week 44th Sunday 2016

    When ambition ends, happiness begins. 野心消亡之日,正是快乐破茧之时. No ambition, no annoyance. No ambition, no ac ...

  9. navigation和tabbar上的文字.图片 自定义

    [[UITabBarItem appearance] setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor blackColor] ...

  10. 适配器模式/adapter模式/结构型模式

    定义 将类的接口转化为客户端希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作,别名Wrapper(包装器). 适配器模式,最终改变一个已有对象的接口. 使用场景 当有那么个类, ...