一、常見的底部菜單(底部導航欄)的實現(xiàn)方式
常見的實現(xiàn)方式有:
1、TabHost+Activity:資源開銷比較大,官方已經(jīng)不推薦使用。
2、RadioButton(RadioGroup)+Fragment:實現(xiàn)起來比較麻煩。
3、FragmentTabHost+Fragment:實現(xiàn)簡單,資源開銷小,推薦使用。
二、FragmentTabHost介紹 如下圖所示,整一個底部導航欄是一個FragmentTabHost,里面包含的每一個“小按鈕”我們稱之為TabSpec,也就是每一個分頁。TabSpec里面需要有指示器Indicator,用來指示用戶選中了哪一個,里面一般包含一張圖片和文字描述。
三、FragmentTabHost具體實現(xiàn)方法
核心的實現(xiàn)步驟以及注意點有:
1、所用的Activity必須要繼承FragmentActivity,不然項目就會崩潰。
2、調(diào)用FragmentTabHost的setup()方法,設置FragmentManager,以及指定用于裝載Fragment的布局容器。
3、調(diào)用FragmentTabHost的addTab()方法添加分頁。
四、代碼
要使用FragmentTabHost,首先需要布局中添加進來,這里我們并沒有使用官方提供的v4支持包中的FragmentTabHost,而是使用了我們自定義的FragmentTabHost,主要是因為官方提供的FragmentTabHost并沒有進行優(yōu)化,每次都會重新初始化一次Fragment。自定義FragmentTabHost的代碼會在附件給出。
第一個FrameLayout是用于裝載Fragment的,第二個Fragment只是官方文檔要求我們這樣寫的而已,官方要求我們將Fragment放在導航欄之下,與我們的需求剛好相反了。
再仔細看布局文件,主要是通過LinearLayout的weight屬性來控制整個豎直方向的分配,具體不再贅述。
<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/realtabcontent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/bg_color"/> <com.nan.cnshop.widget.FragmentTabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0"/> </com.nan.cnshop.widget.FragmentTabHost> </LinearLayout>
在代碼當中,先通過ID找到FragmentTabHost,然后就可以進行配置了,具體看代碼的注釋。
public class MainActivity extendsBaseActivity { private FragmentTabHost tabHost; //用于裝載每一個分頁的Tab private List<Tab> tabs = null; @Override public void initView() { setContentView(R.layout.activity_main); tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); } @Override public void initData() { initTabs(); } private void initTabs() { //調(diào)用setup()方法,設置FragmentManager,以及指定用于裝載Fragment的布局容器 tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); //新建5個分頁,并且添加到List當中,便于管理,其中的圖標我們使用了selector進行狀態(tài)選擇,即選中的時候會變色。 Tab home = new Tab(HomeFragment.class, R.string.home, R.drawable.selector_icon_home); Tab hot = new Tab(HotFragment.class, R.string.hot, R.drawable.selector_icon_hot); Tab cate = new Tab(CategoryFragment.class, R.string.catagory, R.drawable.selector_icon_category); Tab cart = new Tab(CartFragment.class, R.string.cart, R.drawable.selector_icon_cart); Tab mine = new Tab(MineFragment.class, R.string.mine, R.drawable.selector_icon_mine); tabs = new ArrayList<>(); tabs.add(home); tabs.add(hot); tabs.add(cate); tabs.add(cart); tabs.add(mine); for (Tab tab : tabs) { //新建5個TabSpec,并且設置好它的Indicator TabHost.TabSpec tabSpec = tabHost.newTabSpec(getString(tab.getTitle())); View view = View.inflate(this, R.layout.tab_indicator, null); TextView tv_tab_txt = (TextView) view.findViewById(R.id.txt_indicator); ImageView iv_tab_icon = (ImageView) view.findViewById(R.id.icon_tab); tv_tab_txt.setText(tab.getTitle()); iv_tab_icon.setImageResource(tab.getIcon()); tabSpec.setIndicator(view); //把每個TabSpec添加到FragmentTabHost里面 tabHost.addTab(tabSpec, tab.getFragment(), null); } //去掉分隔線 tabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE); //設置當前默認的分頁為第一頁 tabHost.setCurrentTab(0); } @Override public void initListener() { } @Override public void processClick(View v) { } }
需要注意的是,BaseActivity已經(jīng)繼承了FragmentActivity了。每一個TabSpec中Indicator的布局文件只有一個ImageView和一個TextView,具體布局代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" android:orientation="vertical" android:paddingBottom="3dp" android:paddingTop="3dp"> <ImageView android:id="@+id/icon_tab" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/txt_indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:textColor="@color/selector_tab_text"/> </LinearLayout>
最需要注意的是我們的TextView的文字顏色是通過selector進行狀態(tài)選擇的。需要注意的是,這并不是圖片,只是顏色,不能放在drawable目錄下,而應該放在color目錄下。
|