使用Fragment实现类似TabHost标签栏的效果
在前几天,我写了篇《Android TabHost的使用》简单的介绍了其使用的方法,但是在实现的时候发现TabHost已经被官方遗弃了。虽然我觉得TabHost还是多好用的(可能因为我这种菜鸟不清楚吧)不知道为什么官方会遗弃,但应该还是有原因的吧。
首先,我们来简单的了解一下Fragment。Fragment是Android在3.0中引入的概念用来在一个Activity中描述一些行为或一部分用户界面,支持不同分辨率屏幕的动态和灵活的UI设计。Fragment必须总是被嵌入到一个Activity中,它们的生命周期直接被其所属的宿主Activity的生命周期所影响。
创建Fragment的方法有两种:
- 在布局文件中声明Fragment。
- 从布局文件中读取并生成Fragemnt(使用onCreate()的方法提供的LayoutInflater对象参数)。
每一个Fragment都需要一个唯一的标识,如果Activity重启,系统可以用这个标识来回复Fragment(也可以用来处理Fragment事务,例如移除它),有三种方法来为一个 Fragment提供一个标识:
- 为android:id属性提供一个唯一的ID。
- 为android:tag属性提供一个唯一字符串。
- 如果以上两个都没有提供,则系统使用容器view的ID。
好了,言归正传,我们还是来了解一下Fragment实现类似TabHost标签栏的效果吧。
(这个例子是同学给我的,不知道是他自己做的还是在网上找的Demo)
我们先来看看,效果图:

首先还是从布局文件开始吧:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/tab_bg" > <RelativeLayout
android:id="@+id/message_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" > <ImageView
android:id="@+id/message_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/message_unselected" /> <TextView
android:id="@+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="消息"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout> <RelativeLayout
android:id="@+id/contacts_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" > <ImageView
android:id="@+id/contacts_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/contacts_unselected" /> <TextView
android:id="@+id/contacts_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="联系人"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout> <RelativeLayout
android:id="@+id/news_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" > <ImageView
android:id="@+id/news_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/news_unselected" /> <TextView
android:id="@+id/news_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="动态"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout> <RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" > <ImageView
android:id="@+id/setting_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/setting_unselected" /> <TextView
android:id="@+id/setting_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="设置"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout>
</LinearLayout> </LinearLayout>
contacts_layout.xml
<?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" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" > <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/contacts_selected" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="这是联系人界面"
android:textSize="20sp" />
</LinearLayout> </RelativeLayout>
message_layout.xml
<?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" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" > <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/message_selected" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="这是消息界面"
android:textSize="20sp" />
</LinearLayout> </RelativeLayout>
news_layout.xml
<?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" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" > <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/news_selected" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="这是动态界面"
android:textSize="20sp" />
</LinearLayout> </RelativeLayout>
setting_layout.xml
<?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" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" > <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/setting_selected" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="这是设置界面"
android:textSize="20sp" />
</LinearLayout>
</RelativeLayout>
然后来实现JAVA代码:
MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
/**
* 用于展示消息的Fragment
*/
private MessageFragment messageFragment;
/**
* 用于展示联系人的Fragment
*/
private ContactsFragment contactsFragment;
/**
* 用于展示动态的Fragment
*/
private NewsFragment newsFragment;
/**
* 用于展示设置的Fragment
*/
private SettingFragment settingFragment;
/**
* 消息界面布局
*/
private View messageLayout;
/**
* 联系人界面布局
*/
private View contactsLayout;
/**
* 动态界面布局
*/
private View newsLayout;
/**
* 设置界面布局
*/
private View settingLayout;
/**
* 在Tab布局上显示消息图标的控件
*/
private ImageView messageImage;
/**
* 在Tab布局上显示联系人图标的控件
*/
private ImageView contactsImage;
/**
* 在Tab布局上显示动态图标的控件
*/
private ImageView newsImage;
/**
* 在Tab布局上显示设置图标的控件
*/
private ImageView settingImage;
/**
* 在Tab布局上显示消息标题的控件
*/
private TextView messageText;
/**
* 在Tab布局上显示联系人标题的控件
*/
private TextView contactsText;
/**
* 在Tab布局上显示动态标题的控件
*/
private TextView newsText;
/**
* 在Tab布局上显示设置标题的控件
*/
private TextView settingText;
/**
* 用于对Fragment进行管理
*/
private FragmentManager fragmentManager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();
fragmentManager = getFragmentManager();
// 第一次启动时选中第0个tab
setTabSelection(0);
}
/**
* 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。
*/
private void initViews() {
messageLayout = findViewById(R.id.message_layout);
contactsLayout = findViewById(R.id.contacts_layout);
newsLayout = findViewById(R.id.news_layout);
settingLayout = findViewById(R.id.setting_layout);
messageImage = (ImageView) findViewById(R.id.message_image);
contactsImage = (ImageView) findViewById(R.id.contacts_image);
newsImage = (ImageView) findViewById(R.id.news_image);
settingImage = (ImageView) findViewById(R.id.setting_image);
messageText = (TextView) findViewById(R.id.message_text);
contactsText = (TextView) findViewById(R.id.contacts_text);
newsText = (TextView) findViewById(R.id.news_text);
settingText = (TextView) findViewById(R.id.setting_text);
messageLayout.setOnClickListener(this);
contactsLayout.setOnClickListener(this);
newsLayout.setOnClickListener(this);
settingLayout.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.message_layout:
// 当点击了消息tab时,选中第1个tab
setTabSelection(0);
break;
case R.id.contacts_layout:
// 当点击了联系人tab时,选中第2个tab
setTabSelection(1);
break;
case R.id.news_layout:
// 当点击了动态tab时,选中第3个tab
setTabSelection(2);
break;
case R.id.setting_layout:
// 当点击了设置tab时,选中第4个tab
setTabSelection(3);
break;
default:
break;
}
}
/**
* 根据传入的index参数来设置选中的tab页。
*
* @param index
* 每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。
*/
private void setTabSelection(int index) {
// 每次选中之前先清楚掉上次的选中状态
clearSelection();
// 开启一个Fragment事务
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragments(transaction);
switch (index) {
case 0:
// 当点击了消息tab时,改变控件的图片和文字颜色
messageImage.setImageResource(R.drawable.message_selected);
messageText.setTextColor(Color.WHITE);
if (messageFragment == null) {
// 如果MessageFragment为空,则创建一个并添加到界面上
messageFragment = new MessageFragment();
transaction.add(R.id.content, messageFragment);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(messageFragment);
}
break;
case 1:
// 当点击了联系人tab时,改变控件的图片和文字颜色
contactsImage.setImageResource(R.drawable.contacts_selected);
contactsText.setTextColor(Color.WHITE);
if (contactsFragment == null) {
// 如果ContactsFragment为空,则创建一个并添加到界面上
contactsFragment = new ContactsFragment();
transaction.add(R.id.content, contactsFragment);
} else {
// 如果ContactsFragment不为空,则直接将它显示出来
transaction.show(contactsFragment);
}
break;
case 2:
// 当点击了动态tab时,改变控件的图片和文字颜色
newsImage.setImageResource(R.drawable.news_selected);
newsText.setTextColor(Color.WHITE);
if (newsFragment == null) {
// 如果NewsFragment为空,则创建一个并添加到界面上
newsFragment = new NewsFragment();
transaction.add(R.id.content, newsFragment);
} else {
// 如果NewsFragment不为空,则直接将它显示出来
transaction.show(newsFragment);
}
break;
case 3:
default:
// 当点击了设置tab时,改变控件的图片和文字颜色
settingImage.setImageResource(R.drawable.setting_selected);
settingText.setTextColor(Color.WHITE);
if (settingFragment == null) {
// 如果SettingFragment为空,则创建一个并添加到界面上
settingFragment = new SettingFragment();
transaction.add(R.id.content, settingFragment);
} else {
// 如果SettingFragment不为空,则直接将它显示出来
transaction.show(settingFragment);
}
break;
}
transaction.commit();
}
/**
* 清除掉所有的选中状态。
*/
private void clearSelection() {
messageImage.setImageResource(R.drawable.message_unselected);
messageText.setTextColor(Color.parseColor("#82858b"));
contactsImage.setImageResource(R.drawable.contacts_unselected);
contactsText.setTextColor(Color.parseColor("#82858b"));
newsImage.setImageResource(R.drawable.news_unselected);
newsText.setTextColor(Color.parseColor("#82858b"));
settingImage.setImageResource(R.drawable.setting_unselected);
settingText.setTextColor(Color.parseColor("#82858b"));
}
/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction
* 用于对Fragment执行操作的事务
*/
private void hideFragments(FragmentTransaction transaction) {
if (messageFragment != null) {
transaction.hide(messageFragment);
}
if (contactsFragment != null) {
transaction.hide(contactsFragment);
}
if (newsFragment != null) {
transaction.hide(newsFragment);
}
if (settingFragment != null) {
transaction.hide(settingFragment);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
ContactsFragment.java
public class ContactsFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View contactsLayout = inflater.inflate(R.layout.contacts_layout,
container, false);
return contactsLayout;
}
}
MessageFragment.java
public class MessageFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View messageLayout = inflater.inflate(R.layout.message_layout, container, false);
return messageLayout;
}
}
NewsFragment.java
public class NewsFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsLayout = inflater.inflate(R.layout.news_layout, container,
false);
return newsLayout;
}
}
SettingFragment.java
public class SettingFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View settingLayout = inflater.inflate(R.layout.setting_layout,
container, false);
return settingLayout;
}
}
好了,除了资源文件以外,XML和JAVA文件都已完成。运行即可。
Demo下载:http://pan.baidu.com/s/1xSD9G
使用Fragment实现类似TabHost标签栏的效果的更多相关文章
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3360938.html 如新浪微博下面的标签切换功能,我以前也写过一篇博文(http:/ ...
- Android使用Fragment来实现TabHost的功能
http://www.cnblogs.com/tiantianbyconan/p/3360938.html 好了,到此为止,我们已经用Fragment实现了类似TabHost的功能了,下面来看下各个F ...
- CSS - toggle collapse 类似bootstrap的展开效果
问题:toggle collapse 类似bootstrap的展开效果(展开一个关闭另一个) Demo:http://jsfiddle.net/JSDavi/L47vscw4/ 方案:使用transi ...
- 实现类似QQ的折叠效果
// 主要核心是点击自定义header来展开和收起每一组里面的cell,模型里面应该有isShow此属性来记录开展还是收起. // ViewController.m// 实现类似QQ的折叠效果/ ...
- 怎么实现类似星星闪烁的效果(box-shadow)
有时候设计希望我们能够在页面实现类似星星闪烁的效果,如图: 我的解决办法是用box-shadow: html <div class="star04 active-blink" ...
- 创意HTML5文字特效 类似翻页的效果
原文:创意HTML5文字特效 类似翻页的效果 之前在网上看到一款比较有新意的HTML5文字特效,文字效果是当鼠标滑过是出现翻开折叠的效果,类似书本翻页.于是我兴致勃勃的点开源码看了一下,发现其实实现也 ...
- 如何在Python 2.X中也达到类似nonlocal关键字的效果
nonlocal关键字时Python 3.X中引入的,目的是让内层函数可以修改外层函数的变量值,而该关键字在Python 2.X中是不存在的.那么,要在Python 2.X中达到类型达到类似nonlo ...
- Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果
1.首先上效果图 2.本例实现的效果主要适用于当前页面有多个页签时.进行Fragment切换时,能够利用不同的Menu样式与当前Fragment中的内容进行配合,能够大大添加复用性,看到效果图后,以下 ...
- 通过JazzyViewPager来实现Fragment页面间的动画切效果
JazzyViewPager 开源项目地址: https://github.com/jfeinstein10/JazzyViewPager 其实实现它还是蛮简单的,有两个关键点,一是使用扩展Fragm ...
随机推荐
- javaweb之servlet 全解
①Servlet概述 ⑴什么是Servlet Servlet是JavaWeb的三大组件之一,它属于动态资源.Servlet的作用是处理请求, 服务器会把接收到的请求交给Servlet来处理,在Serv ...
- NOIP2015 提高组(senior) 解题报告
过了这么久才来发解题报告,蒟蒻实在惭愧 /w\ Day1 T1 [思路] 模拟 [代码] #include<iostream> #include<cstring> #inclu ...
- LA4329 Ping pong 树状数组
题意:一条大街上住着n个乒乓球爱好者,经常组织比赛切磋技术.每个人都有一个能力值a[i].每场比赛需要三个人:两名选手,一名裁判.他们有个奇怪的约定,裁判必须住在两名选手之间,而裁判的能力值也必须在两 ...
- POJ-1981 Circle and Points 单位圆覆盖
题目链接:http://poj.org/problem?id=1981 容易想到直接枚举两个点,然后确定一个圆来枚举,算法复杂度O(n^3). 这题还有O(n^2*lg n)的算法.将每个点扩展为单位 ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- HDU4737 - A Bit Fun(线段树)
题目大意 给你一个数组a,定义f(i,j)=ai|ai+1|ai+2|⋯|aj ,|为or运算,求满足f(i,j)<m的二元组个数,N≤105,m≤230 题解 枚举起点i,然后找出最靠右的k, ...
- Dynamices CRM JS 类库 神器 XrmServiceToolkit - A Microsoft Dynamics CRM 2011 & CRM 2013 JavaScript Library
XrmServiceToolkit - A Microsoft Dynamics CRM 2011 & CRM 2013 JavaScript Library http://xrmservic ...
- 在C#中生成唯一的字符串和数字【GUID】转
转自:http://www.cnblogs.com/lcwzj/archive/2009/04/16/1436992.html 当我们想要获得一个唯一的key的时候,通常会想到GUID.这个key非常 ...
- storm出现的背景
storm出现的背景 互联网从诞生的第一时间起,对世界的最大改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家有对信息实时响应.实时交互的需求,所以软件行业除了个人操作系统之外,数 ...
- eclipse中的maven配置
1.下载最新版eclipse,包含maven版本 2.配置maven本地仓库(修改settings.xml)