Android 使用 FragmentTabHost + Fragment 實現 微信 底部菜單
利用FragmentTabHost實現底部菜單,在該底部菜單中,包括了4個TabSpec,每個TabSpec中包含了一個View,而View中包含了一個ImageView和一個TextView。
一、先演示下效果:

二、TabHost基本介紹
TabWidget : 該組件就是TabHost標簽頁中上部 或者 下部的按鈕, 可以點擊按鈕切換選項卡;
TabSpec : 代表了選項卡界面, 添加一個TabSpec即可添加到TabHost中;
-- 創建選項卡 : newTabSpec(String tag), 創建一個選項卡;
-- 添加選項卡 : addTab(tabSpec);
三、使用步驟
1、定義布局 : 在XML文件中使用 FragmentTabHost 組件, 並在其中定義一個FrameLayout選項卡內容;
<?xml version="1.0" encoding="utf-8"?> <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=".ui.activity.MainActivity"> <FrameLayout android:id="@+id/real_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <android.support.v4.app.FragmentTabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff"> <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、定義 Indicator中的View 文件:main_tab_indicator.xml
<?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/iv_tab_icon" android:layout_width="24dp" android:layout_height="24dp" android:layout_marginTop="5dp" android:src="@drawable/main_tab_btn_news" /> <TextView android:id="@+id/tv_tab_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="首頁" android:textColor="@color/main_tab_text_color" android:textSize="10sp" /> </LinearLayout>
一張圖片,一個文本
3、定義Tab MainTabItem.java
package com.jack.appnews.widget;
public class MainTabItem {
private int Image;
private int Text;
private Class Fragment;
public MainTabItem(int image, int text, Class fragment) {
Image = image;
Text = text;
Fragment = fragment;
}
public int getImage() {
return Image;
}
public void setImage(int image) {
Image = image;
}
public int getText() {
return Text;
}
public void setText(int text) {
Text = text;
}
public Class getFragment() {
return Fragment;
}
public void setFragment(Class fragment) {
Fragment = fragment;
}
}
4、在MainActivity中編寫邏輯
核心邏輯如下 (代碼中有說明,共5步)
//1)實例化4個Tab類的對象
mTabs.add(new MainTabItem(R.drawable.main_tab_btn_news, R.string.main_tab_news, NewsListFragment.class));
mTabs.add(new MainTabItem(R.drawable.main_tab_btn_video, R.string.main_tab_video, VideoListFragment.class));
mTabs.add(new MainTabItem(R.drawable.main_tab_btn_image, R.string.main_tab_image, ImageListFragment.class));
mTabs.add(new MainTabItem(R.drawable.main_tab_btn_mine, R.string.main_tab_mine, MineFragment.class));
//2)調用 setup 方法
mTabHost.setup(this, getSupportFragmentManager(), R.id.real_content);
//3)添加 Tab
for (MainTabItem tab : mTabs) {
TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText())).setIndicator(getTabItemView(tab));
mTabHost.addTab(tabSpec, tab.getFragment(), null);
}
//4)去除掉底部菜單圖表之間的分割線
if (android.os.Build.VERSION.SDK_INT > 10) {
mTabHost.getTabWidget().setShowDividers(0);
}
//5)事件綁定
mTabHost.setOnTabChangedListener(this);
完整代碼: MainActivity.java
package com.jack.appnews.ui.activity;
import android.support.v4.app.FragmentTabHost;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;
import com.jack.appnews.R;
import com.jack.appnews.ui.BaseActivity;
import com.jack.appnews.ui.fragment.ImageListFragment;
import com.jack.appnews.ui.fragment.MineFragment;
import com.jack.appnews.ui.fragment.NewsListFragment;
import com.jack.appnews.ui.fragment.VideoListFragment;
import com.jack.appnews.widget.MainTabItem;
import java.util.ArrayList;
import butterknife.BindView;
public class MainActivity extends BaseActivity implements TabHost.OnTabChangeListener { @BindView(android.R.id.tabhost) FragmentTabHost mTabHost; private long exitTime = 0; private ArrayList<MainTabItem> mTabs = new ArrayList<>(4); @Override protected int inflateLayoutId() { return R.layout.activity_main; } @Override protected void initViews() { initTabHost(); } protected void initTabHost() { //1)實例化4個Tab類的對象 mTabs.add(new MainTabItem(R.drawable.main_tab_btn_news, R.string.main_tab_news, NewsListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_video, R.string.main_tab_video, VideoListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_image, R.string.main_tab_image, ImageListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_mine, R.string.main_tab_mine, MineFragment.class)); //2)調用 setup 方法 mTabHost.setup(this, getSupportFragmentManager(), R.id.real_content); //3)添加 Tab for (MainTabItem tab : mTabs) { TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText())).setIndicator(getTabItemView(tab)); mTabHost.addTab(tabSpec, tab.getFragment(), null); } //4)去除掉底部菜單圖表之間的分割線 if (android.os.Build.VERSION.SDK_INT > 10) { mTabHost.getTabWidget().setShowDividers(0); } //5)事件綁定 mTabHost.setOnTabChangedListener(this); } /** * 設置Indicator中的View * * @param tab * @return */ private View getTabItemView(MainTabItem tab) { View view = getLayoutInflater().inflate(R.layout.main_tab_indicator, null); ImageView Tab_img = (ImageView) view.findViewById(R.id.iv_tab_icon); TextView Tab_txt = (TextView) view.findViewById(R.id.tv_tab_text); Tab_img.setBackgroundResource(tab.getImage()); Tab_txt.setText(tab.getText()); return view; } @Override public void onTabChanged(String tabId) { final int size = mTabHost.getTabWidget().getTabCount(); for (int i = 0; i < size; i++) { View v = mTabHost.getTabWidget().getChildAt(i); if (i == mTabHost.getCurrentTab()) { v.setSelected(true); } else { v.setSelected(false); } } supportInvalidateOptionsMenu(); } @Override public void onBackPressed() { if ((System.currentTimeMillis() - exitTime) > 2000) { exitTime = System.currentTimeMillis(); } else { finish(); System.exit(0); } } }
四、源代碼地址
Talk is cheap. Show me the code
話不多說,代碼在這里下載!
https://github.com/wukong1688/Android-BaseTabHost
這是我用FragmentTabHost + ViewPager + XRecycleList 實現的 標簽切換 + 列表上滑加載+列表下滑刷新
其中 列表上滑加載+列表下滑刷新 可參考下一篇文章:
Android 支持下拉刷新、上拉加載更多 的 XRecyclerview
如果覺得有幫助,歡迎在 Github 為我 star!
五、參考文章
https://www.jianshu.com/p/491386d6435c
https://www.cnblogs.com/langfei8818/p/6349354.html
