1.FragmentTabHost这个类是v4包下的,使用起来也是非常方便的
先贴上布局代码
<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"
android:orientation="vertical"
tools:context="com.fanday.wechat.MainActivity" >
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:background="#eee"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp" >
</FrameLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
android.support.v4.app.FragmentTabHost节点下的id都要使用系统的id,要不然系统会找不到控件报错。TabHost导航默认出现在页面的顶部的,这里我们使用一个非常巧妙地
方法,就是把TabHost自带的FrameLayout内容区域给设置0dp,然后自己再给一个FrameLayout id和这个一样,这样系统就去找咱们自己写的这个Framelayout了,成功的把导航
弄到了底部.
2.activity中的代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
addSpec();
tabHost.setOnTabChangedListener(this);
tabHost.getTabWidget().setDividerDrawable(android.R.color.transparent);
}
先初始化Tabhost 然后在addSpec()方法中添加标签Spec,最后给tabHost设置Tab改变的监听,并且把分割线隐藏
private void addSpec() {
chat = tabHost.newTabSpec(TAG_CHAT);
chat_view = new TabIndicatorView(this);
chat_view.setIcon(R.drawable.tab_icon_chat_focus,R.drawable.tab_icon_chat_normal);
chat_view.setIconON();
chat_view.setUnReadNum(22);
chat_view.setTitle("消息");
chat.setIndicator(chat_view);
tabHost.addTab(chat, ChatFragment.class, null);
contact = tabHost.newTabSpec(TAG_CONN);
contact_view = new TabIndicatorView(this);
contact_view.setIcon(R.drawable.tab_icon_contact_focus,R.drawable.tab_icon_contact_normal);
contact_view.setIconOff();
contact_view.setUnReadNum(0);
contact_view.setTitle("联系");
contact.setIndicator(contact_view);
tabHost.addTab(contact, ContactFragment.class, null);
discover = tabHost.newTabSpec(TAG_FIND);
discover_view = new TabIndicatorView(this);
discover_view.setIcon(R.drawable.tab_icon_discover_focus,R.drawable.tab_icon_discover_normal);
discover_view.setIconOff();
discover_view.setUnReadNum(0);
discover_view.setTitle("发现");
discover.setIndicator(discover_view);
tabHost.addTab(discover, DiscoverFragment.class, null);
me = tabHost.newTabSpec(TAG_ME);
me_view = new TabIndicatorView(this);
me_view.setIcon(R.drawable.tab_icon_me_focus,R.drawable.tab_icon_me_normal);
me_view.setIconOff();
me_view.setUnReadNum(100);
me_view.setTitle("我");
me.setIndicator(me_view);
tabHost.addTab(me, MeFragment.class, null);
}
这里的TabIndicatorView是我们自定义的组合控件,代码如下:
package com.fanday.wechat.view;
import com.fanday.wechat.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class TabIndicatorView extends RelativeLayout {
private ImageView iv;
private TextView tv_unRead;
private TextView tv_msg;
private int offIcon,onIcon;
public TabIndicatorView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TabIndicatorView(Context context) {
this(context, null);
}
private void init() {
LayoutInflater.from(getContext()).inflate(R.layout.tab_indicator, this);
iv = (ImageView) findViewById(R.id.indicator_icon);
tv_unRead = (TextView) findViewById(R.id.unread_num);
tv_msg = (TextView) findViewById(R.id.indicator_text);
}
public void setIcon(int onIcon,int offIcon) {
this.onIcon=onIcon;
this.offIcon=offIcon;
}
public void setIconON(){
iv.setImageResource(onIcon);
}
public void setIconOff(){
iv.setImageResource(offIcon);
}
public void setUnReadNum(int num) {
if (num == 0) {
tv_unRead.setVisibility(View.GONE);
} else if (num <= 99) {
tv_unRead.setVisibility(View.VISIBLE);
tv_unRead.setText(num + "");
} else {
tv_unRead.setText("99+");
}
}
public void setTitle(String tab) {
tv_msg.setText(tab);
}
}
view的布局:
<?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="wrap_content"
android:gravity="center"
android:padding="5dp" >
<ImageView
android:layout_centerHorizontal="true"
android:id="@+id/indicator_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/tab_icon_chat_normal" />
<TextView
android:id="@+id/unread_num"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignRight="@+id/indicator_icon"
android:layout_alignTop="@+id/indicator_icon"
android:background="@drawable/unread_dot"
android:gravity="center"
android:text="5"
android:textColor="#fff"
android:textSize="10sp" />
<TextView
android:id="@+id/indicator_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/indicator_icon"
android:layout_centerHorizontal="true"
android:text="消息"
android:textSize="10sp" />
</RelativeLayout>
未读提醒的background用到了一个shape资源:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="15dp"
android:height="15dp"
/>
<stroke android:width="2dp"
android:color="#aaa"/>
<solid android:color="#ff0000"/>
</shape>
最后是tabHost的Tab改变的时候的逻辑:
@Override
public void onTabChanged(String tabId) {
chat_view.setIconOff();
contact_view.setIconOff();
discover_view.setIconOff();
me_view.setIconOff();
switch (tabId) {
case TAG_CHAT:
chat_view.setIconON();
break;
case TAG_CONN:
contact_view.setIconON();
break;
case TAG_FIND:
discover_view.setIconON();
break;
case TAG_ME:
me_view.setIconON();
break;
default:
break;
}
tabHost.setCurrentTabByTag(tabId);
}
这样就完成了,底部导航加fragment切换的效果了
源码下载 : 源码