既然 Fragment 取代了TabActivity,当然 TabActivity 的能实现的菜单栏,Fragment 当然也能实现。主要其实就是通过菜单栏的点击事件切换 Fragment 的显示和隐藏。

来看看栗子吧:

1.效果图来了:

2.代码具体实现

2.1 自定义底部菜单栏实现方式

(1)对应的 Fragment 编辑代码和布局实现在前面的Fragment介绍和简单实现  中已经有提及,代码中没复杂的地方,此处略过,具体可看实例代码。

(2)菜单栏实现,这里使用代码实现的,其实也可以用布局文件实现,代码如下:

package com.yanis.yc_ui_fragment_menu;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; /**
*
* @author YeChao
* @功能描述:自定义底部工具栏
*
*/
public class ViewIndicator extends LinearLayout implements OnClickListener {
private int mDefaultIndicator = 0; // 默认的选定View private static int mCurIndicator; // 当前选定View private static View[] mIndicators; // View集合 private OnIndicateListener mOnIndicateListener; // 对应的监听器
// 对应的图标Tag
private static final String TAG_ICON_0 = "icon_tag_0";
private static final String TAG_ICON_1 = "icon_tag_1";
private static final String TAG_ICON_2 = "icon_tag_2";
private static final String TAG_ICON_3 = "icon_tag_3";
private static final String TAG_ICON_4 = "icon_tag_4";
// 对应的文字Tag
private static final String TAG_TEXT_0 = "text_tag_0";
private static final String TAG_TEXT_1 = "text_tag_1";
private static final String TAG_TEXT_2 = "text_tag_2";
private static final String TAG_TEXT_3 = "text_tag_3";
private static final String TAG_TEXT_4 = "text_tag_4";
// 未选中状态
private static final int COLOR_UNSELECT = Color.argb(100, 0xff, 0xff, 0xff);
// 选中状态
private static final int COLOR_SELECT = Color.WHITE; // 构造函数
public ViewIndicator(Context context) {
super(context);
} public ViewIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
mCurIndicator = mDefaultIndicator;
setOrientation(LinearLayout.HORIZONTAL);// 水平布局
init();
} /**
* 菜单视图布局
*
* @param iconResID
* 图片资源ID
* @param stringResID
* 文字资源ID
* @param stringColor
* 颜色资源ID
* @param iconTag
* 图片标签
* @param textTag
* 文字标签
* @return
*/
private View createIndicator(int iconResID, int stringResID,
int stringColor, String iconTag, String textTag) {
// 实例一个LinearLayout
LinearLayout view = new LinearLayout(getContext());
view.setOrientation(LinearLayout.VERTICAL);// 垂直布局
// 设置宽高和权重
view.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
view.setGravity(Gravity.CENTER_HORIZONTAL);
view.setBackgroundResource(R.drawable.main_tab_item_bg_normal);
// 实例一个ImageView
ImageView iconView = new ImageView(getContext());
// 设置与该ImageView视图相关联的标记
iconView.setTag(iconTag);
// 设置宽高和权重
iconView.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
iconView.setImageResource(iconResID);// 设置图片资源
// 实例一个TextView
TextView textView = new TextView(getContext());
// 设置与该TextView视图相关联的标记
textView.setTag(textTag);
// 设置宽高和权重
textView.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
// 设置文字颜色
textView.setTextColor(stringColor);
// 设置文字大小
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
// 设置文字资源
textView.setText(stringResID);
// 添加视图到布局中
view.addView(iconView);
view.addView(textView);
// 返回布局视图
return view; } /**
* 初始化视图
*/
private void init() {
mIndicators = new View[5];// 5个View
// 第一个为默认选中的
// 主页main_tab_item_bg_normal
mIndicators[0] = createIndicator(R.drawable.main_tab_item_home_focus,
R.string.tab_item_home, COLOR_SELECT, TAG_ICON_0, TAG_TEXT_0);
mIndicators[0].setBackgroundResource(R.drawable.main_tab_item_bg);
mIndicators[0].setTag(Integer.valueOf(0));
mIndicators[0].setOnClickListener(this);
addView(mIndicators[0]);
// 分类
mIndicators[1] = createIndicator(
R.drawable.main_tab_item_category_normal,
R.string.tab_item_category, COLOR_UNSELECT, TAG_ICON_1,
TAG_TEXT_1);
mIndicators[1].setBackgroundResource(R.drawable.main_tab_item_bg);
mIndicators[1].setTag(Integer.valueOf(1));
mIndicators[1].setOnClickListener(this);
addView(mIndicators[1]);
// 下载
mIndicators[2] = createIndicator(R.drawable.main_tab_item_down_normal,
R.string.tab_item_down, COLOR_UNSELECT, TAG_ICON_2, TAG_TEXT_2);
mIndicators[2].setBackgroundResource(R.drawable.main_tab_item_bg);
mIndicators[2].setTag(Integer.valueOf(2));
mIndicators[2].setOnClickListener(this);
addView(mIndicators[2]);
// 我的
mIndicators[3] = createIndicator(R.drawable.main_tab_item_user_normal,
R.string.tab_item_user, COLOR_UNSELECT, TAG_ICON_3, TAG_TEXT_3);
mIndicators[3].setBackgroundResource(R.drawable.main_tab_item_bg);
mIndicators[3].setTag(Integer.valueOf(3));
mIndicators[3].setOnClickListener(this);
addView(mIndicators[3]);
// 设置
mIndicators[4] = createIndicator(
R.drawable.main_tab_item_setting_normal,
R.string.tab_item_setting, COLOR_UNSELECT, TAG_ICON_4,
TAG_TEXT_4);
mIndicators[4].setBackgroundResource(R.drawable.main_tab_item_bg);
mIndicators[4].setTag(Integer.valueOf(4));
mIndicators[4].setOnClickListener(this);
addView(mIndicators[4]);
} public static void setIndicator(int which) {
// /////////////////清除之前的状态/////////////////////////////////
// mIndicators[mCurIndicator].setBackgroundResource(R.drawable.main_tab_item_bg_normal);
ImageView prevIcon;
TextView prevText;
switch (mCurIndicator) {
case 0:
prevIcon = (ImageView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_ICON_0);
prevIcon.setImageResource(R.drawable.main_tab_item_home);
prevText = (TextView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_TEXT_0);
prevText.setTextColor(COLOR_UNSELECT);
break;
case 1:
prevIcon = (ImageView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_ICON_1);
prevIcon.setImageResource(R.drawable.main_tab_item_category);
prevText = (TextView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_TEXT_1);
prevText.setTextColor(COLOR_UNSELECT);
break;
case 2:
prevIcon = (ImageView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_ICON_2);
prevIcon.setImageResource(R.drawable.main_tab_item_down);
prevText = (TextView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_TEXT_2);
prevText.setTextColor(COLOR_UNSELECT);
break;
case 3:
prevIcon = (ImageView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_ICON_3);
prevIcon.setImageResource(R.drawable.main_tab_item_user);
prevText = (TextView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_TEXT_3);
prevText.setTextColor(COLOR_UNSELECT);
break;
case 4:
prevIcon = (ImageView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_ICON_4);
prevIcon.setImageResource(R.drawable.main_tab_item_setting);
prevText = (TextView) mIndicators[mCurIndicator]
.findViewWithTag(TAG_TEXT_4);
prevText.setTextColor(COLOR_UNSELECT);
break;
}
// /////////////////更新前状态/////////////////////////////////
// mIndicators[which].setBackgroundResource(R.drawable.main_tab_item_bg_focus);
ImageView currIcon;
TextView currText;
/**
* 设置选中状态
*/
switch (which) {
case 0:
currIcon = (ImageView) mIndicators[which]
.findViewWithTag(TAG_ICON_0);
currIcon.setImageResource(R.drawable.main_tab_item_home_focus);
currText = (TextView) mIndicators[which]
.findViewWithTag(TAG_TEXT_0);
currText.setTextColor(COLOR_SELECT);
break;
case 1:
currIcon = (ImageView) mIndicators[which]
.findViewWithTag(TAG_ICON_1);
currIcon.setImageResource(R.drawable.main_tab_item_category_focus);
currText = (TextView) mIndicators[which]
.findViewWithTag(TAG_TEXT_1);
currText.setTextColor(COLOR_SELECT);
break;
case 2:
currIcon = (ImageView) mIndicators[which]
.findViewWithTag(TAG_ICON_2);
currIcon.setImageResource(R.drawable.main_tab_item_down_focus);
currText = (TextView) mIndicators[which]
.findViewWithTag(TAG_TEXT_2);
currText.setTextColor(COLOR_SELECT);
break;
case 3:
currIcon = (ImageView) mIndicators[which]
.findViewWithTag(TAG_ICON_3);
currIcon.setImageResource(R.drawable.main_tab_item_user_focus);
currText = (TextView) mIndicators[which]
.findViewWithTag(TAG_TEXT_3);
currText.setTextColor(COLOR_SELECT);
break;
case 4:
currIcon = (ImageView) mIndicators[which]
.findViewWithTag(TAG_ICON_4);
currIcon.setImageResource(R.drawable.main_tab_item_setting_focus);
currText = (TextView) mIndicators[which]
.findViewWithTag(TAG_TEXT_4);
currText.setTextColor(COLOR_SELECT);
break;
} mCurIndicator = which;
} public interface OnIndicateListener {
public void onIndicate(View v, int which);
} public void setOnIndicateListener(OnIndicateListener listener) {
mOnIndicateListener = listener;
} @Override
public void onClick(View v) {
if (mOnIndicateListener != null) {
int tag = (Integer) v.getTag();
switch (tag) {
case 0:
if (mCurIndicator != 0) {
mOnIndicateListener.onIndicate(v, 0);
setIndicator(0);
}
break;
case 1:
if (mCurIndicator != 1) {
mOnIndicateListener.onIndicate(v, 1);
setIndicator(1);
}
break;
case 2:
if (mCurIndicator != 2) {
mOnIndicateListener.onIndicate(v, 2);
setIndicator(2);
}
break;
case 3:
if (mCurIndicator != 3) {
mOnIndicateListener.onIndicate(v, 3);
setIndicator(3);
}
break;
case 4:
if (mCurIndicator != 4) {
mOnIndicateListener.onIndicate(v, 4);
setIndicator(4);
}
break;
default:
break;
}
}
}
}

ViewIndicator

(3)最后就是主界面代码,切换 Fragment 的显示和隐藏以及菜单栏的选中状态

package com.yanis.yc_ui_fragment_menu;

import com.yanis.yc_ui_fragment_menu.ViewIndicator.OnIndicateListener;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.View; public class MainActivity extends FragmentActivity {
public static Fragment[] mFragments; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setFragmentIndicator(0);
} /**
* 初始化fragment
*/
private void setFragmentIndicator(int whichIsDefault) {
//实例化 Fragment 集合
mFragments = new Fragment[5];
mFragments[0] = getSupportFragmentManager().findFragmentById(R.id.fragment_home);
mFragments[1] = getSupportFragmentManager().findFragmentById(R.id.fragment_category);
mFragments[2] = getSupportFragmentManager().findFragmentById(R.id.fragment_down);
mFragments[3] = getSupportFragmentManager().findFragmentById(R.id.fragment_user);
mFragments[4] = getSupportFragmentManager().findFragmentById(R.id.fragment_setting);
//显示默认的Fragment
getSupportFragmentManager().beginTransaction().hide(mFragments[0])
.hide(mFragments[1]).hide(mFragments[2]).hide(mFragments[3]).hide(mFragments[4]).show(mFragments[whichIsDefault]).commit();
//绑定自定义的菜单栏组件
ViewIndicator mIndicator = (ViewIndicator) findViewById(R.id.indicator);
ViewIndicator.setIndicator(whichIsDefault);
mIndicator.setOnIndicateListener(new OnIndicateListener() {
@Override
public void onIndicate(View v, int which) {
//显示指定的Fragment
getSupportFragmentManager().beginTransaction()
.hide(mFragments[0]).hide(mFragments[1])
.hide(mFragments[2]).hide(mFragments[3]).hide(mFragments[4]).show(mFragments[which]).commit();
}
});
}
}

源代码地址:https://github.com/YeXiaoChao/Yc_ui_fragment_menu


2.2 使用 Fragment+FragmentTabHost 来实现底部菜单栏方式

效果是一样的,只是在上面的基础上使用 FragmentTabHost 来实现底部菜单栏,直接通过 FragmentTabHost 来切换 Fragment 的显示 ,而不是自定义的布局。

(1)修改主布局代码,加入了FragmentTabHost 组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" /> <android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/main_tab_item_bg"> <FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost> </LinearLayout>

(2)单独为Tab按钮选项布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" > <ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:padding="3dp"
android:src="@drawable/main_tab_item_home">
</ImageView> <TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#ffffff">
</TextView> </LinearLayout>

(3) fragment布局界面和之前一样,就不再赘述

(4) Tab选项的自定义按钮中图片资源文件,列出其中一个按钮,指定了按钮的选中状态和不选中状态不同的图片显示

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/main_tab_item_home_focus" android:state_selected="true"/>
<item android:drawable="@drawable/main_tab_item_home_normal"/> </selector>

(5) Tab选项按钮背景资源文件,指定了点击的效果

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- pressed -->
<item android:drawable="@drawable/main_tab_item_bg_focus" android:state_enabled="true" android:state_pressed="true"/> <!-- focused -->
<item android:drawable="@drawable/main_tab_item_bg_focus" android:state_enabled="true" android:state_focused="true"/> <!-- normal -->
<item android:drawable="@drawable/main_tab_item_bg_normal" android:state_enabled="true"/> </selector>

(6) 最后就是主界面代码的改变

package com.yanis.yc_ui_fragment_tabhost;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost.TabSpec;
import android.widget.TextView; /**
*
* @author yechao
* @功能说明 自定义TabHost
*
*/
public class MainActivity extends FragmentActivity {
// 定义FragmentTabHost对象
private FragmentTabHost mTabHost; // 定义一个布局
private LayoutInflater layoutInflater; // 定义数组来存放Fragment界面
private Class fragmentArray[] = { FragmentHome.class,
FragmentCategory.class, FragmentDown.class, FragmentUser.class,
FragmentSetting.class }; // 定义数组来存放按钮图片
private int mImageViewArray[] = { R.drawable.main_tab_item_home,
R.drawable.main_tab_item_category, R.drawable.main_tab_item_down,
R.drawable.main_tab_item_user, R.drawable.main_tab_item_setting }; // Tab选项卡的文字
private String mTextviewArray[] = { "主页", "分类", "下载", "我的", "设置" }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
} /**
* 初始化组件
*/
private void initView() {
// 实例化布局对象
layoutInflater = LayoutInflater.from(this); // 实例化TabHost对象,得到TabHost
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); // 得到fragment的个数
int count = fragmentArray.length; for (int i = 0; i < count; i++) {
// 为每一个Tab按钮设置图标、文字和内容
TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i])
.setIndicator(getTabItemView(i));
// 将Tab按钮添加进Tab选项卡中
mTabHost.addTab(tabSpec, fragmentArray[i], null);
// 设置Tab按钮的背景
mTabHost.getTabWidget().getChildAt(i)
.setBackgroundResource(R.drawable.main_tab_item_bg);
}
} /**
* 给Tab按钮设置图标和文字
*/
private View getTabItemView(int index) {
View view = layoutInflater.inflate(R.layout.tab_item_view, null); ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
imageView.setImageResource(mImageViewArray[index]); TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(mTextviewArray[index]); return view;
}
}

源代码地址:https://github.com/YeXiaoChao/Yc_ui_fragment_tabhost

【Android UI设计与开发】5.底部菜单栏(二)使用Fragment实现底部菜单栏的更多相关文章

  1. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    [Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...

  2. 【转】【Android UI设计与开发】之详解ActionBar的使用,androidactionbar

    原文网址:http://www.bkjia.com/Androidjc/895966.html [Android UI设计与开发]之详解ActionBar的使用,androidactionbar 详解 ...

  3. 【Android UI设计与开发】第02期:引导界面(二)使用ViewPager实现欢迎引导页面

    本系列文章都会以一个程序的实例开发为主线来进行讲解,以求达到一个循序渐进的学习效果,这样更能加深大家对于程序为什么要这样写的用意,理论加上实际的应用才能达到事半功倍的效果,不是吗? 最下方有源码的下载 ...

  4. 【转】【Android UI设计与开发】第07期:底部菜单栏(二)Fragment的详细介绍和使用方法

    原始地址:http://blog.csdn.net/yangyu20121224/article/category/1431917/1 由于TabActivity在Android4.0以后已经被完全弃 ...

  5. 【Android UI设计与开发】9:滑动菜单栏(一)开源项目SlidingMenu的使用和示例

    一.SlidingMenu简介 相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作.很多优秀的应用都采用了 ...

  6. 【Android UI设计与开发】第01期:引导界面(一)ViewPager介绍和使用详解

    做Android开发加起来差不多也有一年多的时间了,总是想写点自己在开发中的心得体会与大家一起交流分享.共同进步,刚开始写也不知该如何下手,仔细想了一下,既然是刚开始写,那就从一个软件给人最直观的感受 ...

  7. 【Android UI设计和开发】动画(Animation)详细说明(一)

    Android开发之动画效果浅析 请尊重他人的劳动成果.转载请注明出处:Android开发之动画效果浅析 程序执行效果图: Android动画主要包括补间动画(Tween)View Animation ...

  8. 【Android UI设计与开发】4.底部菜单栏(一)Fragment介绍和简单实现

    TabActivity在Android4.0以后已经被完全弃用,取而代之的是Fragment.Fragment是Android3.0新增的概念,Fragment翻译成中文是碎片的意思,不过却和Acti ...

  9. 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单

    前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来 ...

随机推荐

  1. git 使用笔记(一)

    1. 环境介绍 windows10 2.使用 2.1 安装git for windows 2.2 创建一个文件夹, 开始git管理 2.3 查看该目录,包括隐藏文件 2.4 把testgit.txt添 ...

  2. poi 导出 excel

    private void exportAssetExcel(HttpServletRequest request, HttpServletResponse response) throws IOExc ...

  3. react与redux学习资料的整理

    **重点内容**React学习 1.新手入门可以访问react的官方网站,如果英语不是特别好的同学可以访问中文版的,具体链接http://reactjs.cn/react/index.html 首页有 ...

  4. html,xhtml和xml

    html,xhtml和xml的定义: 1.html即是超文本标记语言(Hyper Text Markup Language),是最早写网页的语言,但是由于时间早,规范不是很好,大小写混写且编码不规范: ...

  5. ASP.NET MVC下判断用户登录和授权的方法

    日常开发的绝大多数系统中,都涉及到管理用户的登录和授权问题.登录功能(Authentication),针对于所有用户都开放:而授权(Authorization),则对于某种用户角色才开放. 在asp. ...

  6. 实验12:Problem F: 求平均年龄

    Home Web Board ProblemSet Standing Status Statistics   Problem F: 求平均年龄 Problem F: 求平均年龄 Time Limit: ...

  7. 实验12:Problem G: 强悍的矩阵运算来了

    这个题目主要是乘法运算符的重载,卡了我好久,矩阵的乘法用3个嵌套的for循环进行,要分清楚矩阵的乘法结果是第一个矩阵的行,第二个矩阵的列所组成的矩阵. 重载+,*运算符时,可以在参数列表中传两个矩阵引 ...

  8. SharePoint中Event Handler的触发

    一直以来对于Event Handler的感觉就是:添加.编辑和删除动作之前和动作之后,我们在SharePoint系统中可以做的一些事情 不过在最近处理的一个问题中,发现它在触发时机上出了一点问题   ...

  9. iOS设计模式之策略模式

    策略模式(Strategy) 基本理解 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类. 策略模式:它定义了算法家族,分别封装起来, ...

  10. Spring(一)简述

    一.Spring简述 一段费话 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2 ...