android 底部导航栏android fragment实例 怎么实现axtivity

Android UI-实现底部切换标签(fragment) - Android移动开发技术文章_手机开发 - 红黑联盟
Android UI-实现底部切换标签(fragment)
UI-实现底部切换标签(fragment)
本篇博客要分享的一个UI效果&&实现底部切换标签,想必大家在一些应用上面遇到过这种效果了,最典型的就是了,可以左右滑动切换页面,也可以点击标签页滑动页面,它们是如何实现的呢,本篇博客为了简单只介绍如何实现点击底部切换标签页。 先来看看我们想实现的效果图:
这样的页面实现起来其实很简单的,首先我们从布局入手: 分为三部分 第一部分:顶部导航栏布局 第二部分:中部显示内容布局 第三部分:底部标签布局
/BottomTabDemo/res/layout/activity_main.xml
&framelayout android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="/apk/res/android"&
&/framelayout&
以上是布局代码,下面就介绍如何通过点击标签切换Fragment:我们会发现,初始的时候是选中第一个标签页,图片和字体的颜色区别于另外两个标签页,所以我们要做的就是切换标签的时候,就改变标签的状态主要改两个内容:图片文字颜色
然后我们切换标签显示的是不同的Fragment,这里我们有三个Fragment,所以我们定义三个不同的Fragment界面:
/BottomTabDemo/src/com/xiaowu/bottomtab/demo/ZhidaoFragment.java
/BottomTabDemo/src/com/xiaowu/bottomtab/demo/IWantKnowFragment.java
/BottomTabDemo/src/com/xiaowu/bottomtab/demo/MeFragment.java
每个Fragment对应不同的布局文件:/BottomTabDemo/res/layout/main_tab1_fragment.xml
/BottomTabDemo/res/layout/main_tab2_fragment.xml
/BottomTabDemo/res/layout/main_tab3_fragment.xml
ok,这些定义好之后,我们就在主界面上编写切换的代码了,如何对Fragment进行切换呢,定义以下方法:
* 添加或者显示碎片
* @param transaction
* @param fragment
private void addOrShowFragment(FragmentTransaction transaction,
Fragment fragment) {
if (currentFragment == fragment)
if (!fragment.isAdded()) { // 如果当前fragment未被添加,则添加到Fragment管理器中
transaction.hide(currentFragment)
.add(R.id.content_layout, fragment).commit();
transaction.hide(currentFragment).show(fragment).commit();
currentFragment =
完整代码如下:/BottomTabDemo/src/com/xiaowu/bottomtab/demo/MainActivity.java
package com.xiaowu.bottomtab.
import android.os.B
import android.support.v4.app.F
import android.support.v4.app.FragmentA
import android.support.v4.app.FragmentT
import android.view.V
import android.view.View.OnClickL
import android.widget.ImageV
import android.widget.RelativeL
import android.widget.TextV
* 主Activity
* @author wwj_748
public class MainActivity extends FragmentActivity implements OnClickListener {
// 三个tab布局
private RelativeLayout knowLayout, iWantKnowLayout, meL
// 底部标签切换的Fragment
private Fragment knowFragment, iWantKnowFragment, meFragment,
// 底部标签图片
private ImageView knowImg, iWantKnowImg, meI
// 底部标签的文本
private TextView knowTv, iWantKnowTv, meTv;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initTab();
* 初始化UI
private void initUI() {
knowLayout = (RelativeLayout) findViewById(R.id.rl_know);
iWantKnowLayout = (RelativeLayout) findViewById(R.id.rl_want_know);
meLayout = (RelativeLayout) findViewById(R.id.rl_me);
knowLayout.setOnClickListener(this);
iWantKnowLayout.setOnClickListener(this);
meLayout.setOnClickListener(this);
knowImg = (ImageView) findViewById(R.id.iv_know);
iWantKnowImg = (ImageView) findViewById(R.id.iv_i_want_know);
meImg = (ImageView) findViewById(R.id.iv_me);
knowTv = (TextView) findViewById(R.id.tv_know);
iWantKnowTv = (TextView) findViewById(R.id.tv_i_want_know);
meTv = (TextView) findViewById(R.id.tv_me);
* 初始化底部标签
private void initTab() {
if (knowFragment == null) {
knowFragment = new ZhidaoFragment();
if (!knowFragment.isAdded()) {
// 提交事务
getSupportFragmentManager().beginTransaction()
.add(R.id.content_layout, knowFragment).commit();
// 记录当前Fragment
currentFragment = knowF
// 设置图片文本的变化
knowImg.setImageResource(R.drawable.btn_know_pre);
knowTv.setTextColor(getResources()
.getColor(R.color.bottomtab_press));
iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);
iWantKnowTv.setTextColor(getResources().getColor(
R.color.bottomtab_normal));
meImg.setImageResource(R.drawable.btn_my_nor);
meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));
public void onClick(View view) {
switch (view.getId()) {
case R.id.rl_know: // 知道
clickTab1Layout();
case R.id.rl_want_know: // 我想知道
clickTab2Layout();
case R.id.rl_me: // 我的
clickTab3Layout();
* 点击第一个tab
private void clickTab1Layout() {
if (knowFragment == null) {
knowFragment = new ZhidaoFragment();
addOrShowFragment(getSupportFragmentManager().beginTransaction(), knowFragment);
// 设置底部tab变化
knowImg.setImageResource(R.drawable.btn_know_pre);
knowTv.setTextColor(getResources().getColor(R.color.bottomtab_press));
iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);
iWantKnowTv.setTextColor(getResources().getColor(
R.color.bottomtab_normal));
meImg.setImageResource(R.drawable.btn_my_nor);
meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));
* 点击第二个tab
private void clickTab2Layout() {
if (iWantKnowFragment == null) {
iWantKnowFragment = new IWantKnowFragment();
addOrShowFragment(getSupportFragmentManager().beginTransaction(), iWantKnowFragment);
knowImg.setImageResource(R.drawable.btn_know_nor);
knowTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));
iWantKnowImg.setImageResource(R.drawable.btn_wantknow_pre);
iWantKnowTv.setTextColor(getResources().getColor(
R.color.bottomtab_press));
meImg.setImageResource(R.drawable.btn_my_nor);
meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));
* 点击第三个tab
private void clickTab3Layout() {
if (meFragment == null) {
meFragment = new MeFragment();
addOrShowFragment(getSupportFragmentManager().beginTransaction(), meFragment);
knowImg.setImageResource(R.drawable.btn_know_nor);
knowTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));
iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);
iWantKnowTv.setTextColor(getResources().getColor(
R.color.bottomtab_normal));
meImg.setImageResource(R.drawable.btn_my_pre);
meTv.setTextColor(getResources().getColor(R.color.bottomtab_press));
* 添加或者显示碎片
* @param transaction
* @param fragment
private void addOrShowFragment(FragmentTransaction transaction,
Fragment fragment) {
if (currentFragment == fragment)
if (!fragment.isAdded()) { // 如果当前fragment未被添加,则添加到Fragment管理器中
transaction.hide(currentFragment)
.add(R.id.content_layout, fragment).commit();
transaction.hide(currentFragment).show(fragment).commit();
currentFragment =19524人阅读
先看一下QQ、新浪微博、支付宝钱包这三个非常有名的应用,都有一个底部导航栏,我们一般称之‘选项卡’。google官方会叫他们为fixed
tab,不过国内好像很好这么叫的。其实,在anroid 4.x时代,google官方更希望应用的导航放在顶部,通过滑屏和点击标签来切换界面。但是随着ios的的跟风以及用户习惯的养成,这种设计风格的形成也就变成历史遗留问题。在这里我们不讨论哪一个风格好,哪一个风格不好。做为开发人员,我们可能更关注这种司空见惯的界面设计是怎么实现的呢?
在android 2.x时代,我们可能会地使用ActivityGroup来实现这种,但是随着jelly bean的市场份额超过50%,我们会发现有一种新的组建出现了,它叫Fragment()。而这种底部选项卡的风格界面的实现也由ActivityGroup转向了Fragment。先了,费话不多说了,下面我会一步一步教您怎么实现这个界面。在动手之前,我可能需要把我做好的样式图给你看一下,以遍让您有一个心里预期。
其实,我们这个界面的实现,基本没有什么java 代码。不信,你看下面就是主界面的代码:
public&class&MainActivity&extends&Activity&{&&&&&&private&FragmentManager&fragmentM&&&&&&private&RadioGroup&radioG&&&&&&&&@TargetApi(Build.VERSION_CODES.HONEYCOMB)&&&&&&@Override&&&&&&protected&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&requestWindowFeature(Window.FEATURE_NO_TITLE);&&&&&&&&&&setContentView(R.layout.weibo_tab);&&&&&&&&&&&&fragmentManager&=&getFragmentManager();&&&&&&&&&&radioGroup&=&(RadioGroup)&findViewById(R.id.rg_tab);&&&&&&&&&&radioGroup.setOnCheckedChangeListener(new&RadioGroup.OnCheckedChangeListener()&{&&&&&&&&&&&&&&@Override&&&&&&&&&&&&&&public&void&onCheckedChanged(RadioGroup&group,&int&checkedId)&{&&&&&&&&&&&&&&&&&&FragmentTransaction&transaction&=&fragmentManager.beginTransaction();&&&&&&&&&&&&&&&&&&Fragment&fragment&=&FragmentFactory.getInstanceByIndex(checkedId);&&&&&&&&&&&&&&&&&&transaction.replace(R.id.content,&fragment);&&&&&&&&&&&&&&&&&&mit();&&&&&&&&&&&&&&}&&&&&&&&&&});&&&&&&}&&&&}&&
所以哦,亲们,我们把重点放在xml界面的编写上咯。
1.我们可能需要一背景图片像这样的:
2.我们要准备这五个选项卡图片。包括正常和被按下两种状态。所以共十张图片。
3.你要为这五个按钮分别编写selector,文件名为weibolist_attention_selector.xml
&version=&1.0&&encoding=&utf-8&&&&xmlns:android=&/apk/res/android&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_on&&android:state_pressed=&true&&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_on&&android:state_checked=&true&&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_off&&&&&&
这个xml文件挺简单的啊,但是细心的同学可能会地现,你这里为什么要用android:state_checked的啊?为什么不是其他的,比如android:state_selected哦
我想说,其实我这个底部用的是RadioGroup,我怎么判断当前选中的是哪个呢,不选中的是哪个呢。这里最好的选择就是使用RadioGroup,它的最大好处就是彼此的RadioButton具有互斥性,这样就费掉用java代码判断和处理的麻烦了。
4.下面,就要考虑为整个界面布局了。文件名为activity.xml
&version=&1.0&&encoding=&utf-8&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&android:layout_height=&match_parent&&&&&&&android:orientation=&vertical&&&&&&&xmlns:android=&/apk/res/android&&&&&&&&&&&&&&&&&&&&&android:id=&@+id/content&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&android:layout_weight=&1&&&&&&&&&&&&&&&&&&&&android:id=&@+id/rg_tab&&&&&&&&&&&android:orientation=&horizontal&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&wrap_content&&&&&&&&&&&android:background=&@drawable/bg_weibo_listab&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_attention_selector&&&&&&&&&&&&&&&android:text=&微博&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_atme_selector&&&&&&&&&&&&&&&android:text=&\@我&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_comment_selector&&&&&&&&&&&&&&&android:text=&评论&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_mylist_selector&&&&&&&&&&&&&&&android:text=&我的&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_global_selector&&&&&&&&&&&&&&&android:text=&全站&&&&&&&&&&&&
这里可能就有几个问题啦
(1) FrameLayout是干什么的,可能用别的父控件吗?
& & &这个是一个预留的内容控件,以后会用它去呈现Fragment的内容。理论上是可以用别的父控件的,没试过。
(2)android:weight=1,怎么只有一个呢,这样做有对LinearLayout有意义吗?
& & &首先对FragLayout一定要写,不写就会变成这样。但是第二个RadioGroup的weight一定不要写,不然会很难调的。这个我猜测应该会有一个很好weight缺省值自适应的。
& & &我只是猜测啦,具体原因求解释。
(3)weibo_tab样式里面什么内容?
& & 什么内容,如下就可以啦:
&name=&weibo_tab&&&&&&&&name=&android:layout_height&wrap_content&&&&&&&name=&android:layout_width&match_parent&&&&&&&name=&android:layout_weight&1&&&&&&&name=&android:gravity&center&&&&&&&name=&android:textSize&14sp&&&&&&&name=&android:paddingTop&8dip&&&&&&&name=&android:paddingBottom&4dip&&&&&&&name=&android:background&@drawable/weibolist_bottombar_itembg_selector&&&&&&&name=&android:textColor&@color/weibolist_bottombar_textcolor_selector&&&&&&&name=&android:button&@null&&&&
& & 这个style的目地是为了把button相同的设置提取出来,进行很好地重构。
& & 这里可能要解释几个属性weight,其实RadioGroup是继承LinearLayout,设置weight的目的就是把这个底部视图五等分。
& & textColor,这是为是控制底部颜色变化的。button,这个一定要设置,否则就会这样
& &做到这里,我建议你就跑起来,试试效果。虽然没有用到Fragment,但是底部选项已经可以任意切换啦。
& &你是不是已经把它很好的搞定了呢,先恭喜你咯。
5.下一步我来内容填充的界面视图,文件名为fragment.xml
&version=&1.0&&encoding=&utf-8&&&&xmlns:android=&/apk/res/android&&&&&&&android:layout_width=&match_parent&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&&&&&&&&&android:id=&@+id/txt_content&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&android:gravity=&center&&&&&&&&&&&android:padding=&10dp&&&&&&&&&&&android:text=&&&&&&&&&&&&android:textSize=&20sp&&&&&&
这个没有什么解释的,略过。
6.下面我们做五个Fragment内容的呈现,如下:
先有一个BaseFragment抽象类,以被具体的子类继承和实现。
public&abstract&class&BaseFragment&extends&Fragment&{&&&&&&@Override&&&&&&public&View&onCreateView(LayoutInflater&inflater,&ViewGroup&container,&Bundle&savedInstanceState)&{&&&&&&&&&&View&view&=&inflater.inflate(R.layout.fragment,&null);&&&&&&&&&&TextView&textView&=&(TextView)&view.findViewById(R.id.txt_content);&&&&&&&&&&textView.setText(initContent());&&&&&&&&&&return&&&&&&&}&&&&&&&&public&abstract&String&initContent();&&}&&
(1)关注界面
public&class&AttentionFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是关注我界面&;&&&&&&}&&}&&
public&class&AtmeFragment&extends&BaseFragment&{&&&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是@我界面&;&&&&&&}&&}&&
(3)评论界面
public&class&CommentFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是评论我界面&;&&&&&&}&&}&&
(4)我的界面
public&class&MyListFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是我的列表界面&;&&&&&&}&&}&&
(5)全部界面
public&class&GlobalFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是全站界面&;&&&&&&}&&}&&
7.我们还需要一个工厂模式,来实现根据下标的位置返回相应的Fragment。像这样
public&class&FragmentFactory&{&&&&&&public&static&Fragment&getInstanceByIndex(int&index)&{&&&&&&&&&&Fragment&fragment&=&null;&&&&&&&&&&switch&(index)&{&&&&&&&&&&&&&&case&1:&&&&&&&&&&&&&&&&&&fragment&=&new&AttentionFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&2:&&&&&&&&&&&&&&&&&&fragment&=&new&AtmeFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&3:&&&&&&&&&&&&&&&&&&fragment&=&new&CommentFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&4:&&&&&&&&&&&&&&&&&&fragment&=&new&MyListFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&5:&&&&&&&&&&&&&&&&&&fragment&=&new&GlobalFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&}&&&&&&&&&&return&&&&&&&}&&}&&
8.好了,万事具备只欠东风啦。请回到我们刚开始放出去那段代码,那你就已经完成它了。
9.哦,我们还是放上配置文件,贡大家参考。
&manifest&xmlns:android=&/apk/res/android&&&&&&&package=&com.mydream.fragment&&&&&&&android:versionCode=&1&&&&&&&android:versionName=&1.0&&&&&&&&&&&uses-sdk&&&&&&&&&&android:minSdkVersion=&14&&&&&&&&&&&android:targetSdkVersion=&19&&/&&&&&&&&&&application&&&&&&&&&&android:allowBackup=&true&&&&&&&&&&&android:label=&@string/app_name&&&&&&&&&&&android:icon=&@drawable/ic_launcher&&&&&&&&&&&&&activity&&&&&&&&&&&&&&android:name=&.MainActivity&&&&&&&&&&&&&&&android:label=&@string/app_name&&&&&&&&&&&&&&&&&intent-filter&&&&&&&&&&&&&&&&&&&&action&android:name=&android.intent.action.MAIN&&/&&&&&&&&&&&&&&&&&&&&&&category&android:name=&android.intent.category.LAUNCHER&&/&&&&&&&&&&&&&&&&/intent-filter&&&&&&&&&&&&/activity&&&&&&&&/application&&&&&&/manifest&&&
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:244623次
积分:3982
积分:3982
排名:第4016名
原创:150篇
转载:75篇
评论:64条
(4)(3)(11)(6)(2)(1)(5)(3)(5)(6)(10)(12)(11)(5)(1)(13)(2)(8)(2)(1)(16)(13)(4)(2)(1)(11)(3)(3)(10)(5)(5)(1)(16)(13)(11)

我要回帖

更多关于 android fragment实例 的文章

 

随机推荐