您好,登錄后才能下訂單哦!
今天,我將總結(jié)一下Android應(yīng)用中大家經(jīng)常見到的底部導(dǎo)航欄的幾種實(shí)現(xiàn)!
一。TabHost + RadioGroup實(shí)現(xiàn)方式
在我們平時(shí)開發(fā)過程中使用的TabHost是在上方,這里我們簡單修改了一下<TabHost>的布局,讓葉片放到了底部。
main.xml
<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:visibility="gone" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" /> <RadioGroup android:id="@+id/radioGroup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="@drawable/bar" android:gravity="center_vertical" android:orientation="horizontal" > <RadioButton android:id="@+id/rd_home" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/home_icon" android:text="主頁" /> <RadioButton android:id="@+id/rd_wt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/wb_icon_write_n" android:text="發(fā)表" /> <RadioButton android:id="@+id/rd_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/msg_icon" android:text="信息" /> <RadioButton android:id="@+id/rd_more" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/more_icon" android:text="更多" /> </RadioGroup> </LinearLayout> </TabHost>
styles.xml
<style name="main_btn_style"> <item name="android:button">@null</item> <item name="android:textSize">10dp</item> <item name="android:textColor">#ffffff</item> <item name="android:gravity">center_horizontal</item> <item name="android:drawablePadding">4dp</item> <item name="android:layout_weight">1.0</item> <item name="android:background">@drawable/main_btn_bg_d</item> </style>
main_btn_bg_d.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/main_btn_bg" android:state_enabled="true" android:state_pressed="true"></item> <item android:drawable="@drawable/main_btn_bg" android:state_checked="true" android:state_enabled="true"></item> </selector>
這里需要注意的是:
1.main.xml中:TabWidget的id必須是@android:id/tabs,F(xiàn)rameLayout的id必須是 @android:id/tabcontent。
2.把TabWidget的Visibility設(shè)置成了gone!也就是默認(rèn)難看的風(fēng)格不見了:,取而代之的是5個(gè)帶風(fēng)格的單選按鈕.
MainActivity類
package com.zhf.android_tabhost; import android.app.TabActivity; import android.content.Intent; import android.os.Bundle; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TabHost; import android.widget.TabHost.TabSpec; public class MainActivity extends TabActivity { private TabHost tabHost; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tabHost = this.getTabHost(); TabSpec homeSpec = tabHost.newTabSpec("home").setIndicator("home").setContent(new Intent(this,HomeActivity.class)); TabSpec writeSpec = tabHost.newTabSpec("write").setIndicator("write").setContent(new Intent(this,WriteActivity.class)); TabSpec msgSpec = tabHost.newTabSpec("msg").setIndicator("msg").setContent(new Intent(this,MsgActivity.class)); TabSpec moreSpec = tabHost.newTabSpec("more").setIndicator("more").setContent(new Intent(this,MoreActivity.class)); tabHost.addTab(homeSpec); tabHost.addTab(writeSpec); tabHost.addTab(msgSpec); tabHost.addTab(moreSpec); RadioGroup rg = (RadioGroup) this.findViewById(R.id.radioGroup); rg.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rd_home: tabHost.setCurrentTabByTag("home"); break; case R.id.rd_wt: tabHost.setCurrentTabByTag("write"); break; case R.id.rd_msg: tabHost.setCurrentTabByTag("msg"); break; case R.id.rd_more: tabHost.setCurrentTabByTag("more"); break; default: break; } } }); } }
注:
1.由于TabWidget被隱藏,所以相關(guān)的事件也會(huì)無效,這里取巧用RadioGroup與RadioButton的特性來處理切換,然后監(jiān)聽事件調(diào)用setCurrentTabByTag來切換Activity。
2.注意即使TabWidget被隱藏,也要為其設(shè)置indicator,否則會(huì)保持。
效果圖:
(點(diǎn)擊底部就可以實(shí)現(xiàn)切換不同的Activity的操作了,這里需要注意的一點(diǎn)是,切換底部菜單時(shí)不會(huì)重新調(diào)用onCreate()方法的?。。?/span>
二.底部回調(diào)接口實(shí)現(xiàn)(使用Fragment)--- 重要!
這種方式使用了最新的Fragment,采用了底部導(dǎo)航欄回調(diào)接口的方法,來切換底部菜單,并且每次切換回重新調(diào)用onCreate()方法??!
main.xml:
<?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="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".MainActivity" > <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="10" android:orientation="vertical" > <RelativeLayout android:id="@+id/main_title_RelativeLayout" android:layout_width="fill_parent" android:layout_height="50dp" android:background="@drawable/fragment_bottom_normal" android:orientation="horizontal" > <TextView android:id="@+id/main_title_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="主頁" android:textColor="@android:color/white" android:textSize="24sp" /> </RelativeLayout> <FrameLayout android:id="@+id/main_detail_FrameLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" > </FrameLayout> </LinearLayout> <fragment android:id="@+id/bottom_fragment" android:name="com.zhf.frameworkdemo02.fragments.BottomFragment" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
這里由于我們底部菜單我們采用了fragment,所以布局里面要留出位置!
BottomFragment類:
package com.zhf.frameworkdemo02.fragments; import com.zhf.frameworkdemo02.R; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; /** * 頁面底部導(dǎo)航欄 * * @author ZHF * */ public class BottomFragment extends Fragment { //默認(rèn)回調(diào)接口實(shí)現(xiàn)類的對(duì)象 private Callbacks callbacks = defaultCallbacks; /** Fragment和Activity建立關(guān)聯(lián)的時(shí)候調(diào)用 **/ @Override public void onAttach(Activity activity) { super.onAttach(activity); //當(dāng)前類是否實(shí)現(xiàn)了底部導(dǎo)航欄點(diǎn)擊事件回調(diào)接口 if(!(activity instanceof Callbacks)) { throw new IllegalStateException("Activity must implements fragment's callbacks !"); } callbacks = (Callbacks) activity; } /** 為Fragment加載布局時(shí)調(diào)用 **/ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { RadioGroup radioGroup = (RadioGroup) inflater.inflate(R.layout.fragment_bottom, container, false); //綁定監(jiān)聽器 radioGroup.setOnCheckedChangeListener(changeListener); return radioGroup; } /**RadioGroup監(jiān)聽器**/ private OnCheckedChangeListener changeListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { System.out.println(checkedId); callbacks.onItemSelected(checkedId); //調(diào)用接口中方法 } }; public interface Callbacks{ /**導(dǎo)航欄回調(diào)接口**/ public void onItemSelected(int item); } /**默認(rèn)回調(diào)實(shí)現(xiàn)類的對(duì)象**/ private static Callbacks defaultCallbacks = new Callbacks() { @Override public void onItemSelected(int item) { //什么都不干 } }; /**Fragment和Activity解除關(guān)聯(lián)的時(shí)候調(diào)用**/ @Override public void onDetach() { super.onDetach(); callbacks = defaultCallbacks; } }
底部菜單布局fragment_bottom.xml
<?xml version="1.0" encoding="utf-8"?> <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <RadioButton android:id="@+id/fragment_bottom_home" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/fragment_bottom_selector" android:button="@null" android:drawableTop="@drawable/main_readiobutton_home" android:gravity="center" android:text="@string/home" android:textColor="@color/white" android:textSize="12sp" /> <View android:layout_width="1dp" android:layout_height="fill_parent" android:background="@color/white" /> <RadioButton android:id="@+id/fragment_bottom_order" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/fragment_bottom_selector" android:button="@null" android:drawableTop="@drawable/main_readiobutton_order" android:gravity="center" android:text="@string/order" android:textColor="@color/white" android:textSize="12sp" /> <View android:layout_width="1dp" android:layout_height="fill_parent" android:background="@color/white" /> <RadioButton android:id="@+id/fragment_bottom_notice" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/fragment_bottom_selector" android:button="@null" android:drawableTop="@drawable/main_readiobutton_notice" android:gravity="center" android:text="@string/notice" android:textColor="@color/white" android:textSize="12sp" /> <View android:layout_width="1dp" android:layout_height="fill_parent" android:background="@color/white" /> <RadioButton android:id="@+id/fragment_bottom_more" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/fragment_bottom_selector" android:button="@null" android:drawablePadding="3dip" android:drawableTop="@drawable/main_readiobutton_more" android:gravity="center" android:text="@string/more" android:textColor="@color/white" android:textSize="12sp" /> </RadioGroup>
這里我們定義了一個(gè)框架類:GeneralFragment(所有的fragment界面都需繼承它)
package com.zhf.frameworkdemo02.fragments; import java.io.Serializable; import com.zhf.frameworkdemo02.R; import com.zhf.frameworkdemo02.view.OrderView; import com.zhf.frameworkdemo02.view.HomeView; import com.zhf.frameworkdemo02.view.MoreView; import com.zhf.frameworkdemo02.view.NoticeView; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * 框架類,抽象公共方法 * @author ZHF * */ public class GeneralFragment extends Fragment implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private int item; //用于區(qū)分底部菜單項(xiàng) protected static View main_title_RelativeLayout; //標(biāo)題欄 protected final static String key = "Bundle"; //跳轉(zhuǎn)值傳遞key的名稱 @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); if(getArguments() != null) { //根據(jù)接收子類傳來的arguments判斷item的哪一項(xiàng) if(getArguments().containsKey(MainFragment.Item)) { item = getArguments().getInt(MainFragment.Item); } } } /**為Fragment加載布局時(shí)調(diào)用 **/ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_general, container, false); GeneralFragment fragment = null; switch(item) { case R.id.fragment_bottom_home: //初始化主頁 fragment = new HomeView(); break; case R.id.fragment_bottom_order: fragment = new OrderView(); //初始化訂單 break; case R.id.fragment_bottom_notice: fragment = new NoticeView(); //初始化公告 break; case R.id.fragment_bottom_more: fragment = new MoreView(); //初始化更多 break; default: break; } if(fragment != null) { //更換mainView中間的內(nèi)容(home,msg,at,more) getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.general_fragment, fragment).commit(); } main_title_RelativeLayout = ((View) container.getParent()).findViewById(R.id.main_title_RelativeLayout); //將生成的view返回 return view; } /**設(shè)置標(biāo)題**/ protected void setTitle(Object title) { if(main_title_RelativeLayout != null) { //標(biāo)題欄中的文字 TextView mTvTitle = (TextView) main_title_RelativeLayout.findViewById(R.id.main_title_TextView); if(mTvTitle != null) { if(title instanceof Integer) { //整型 mTvTitle.setText((Integer)title); } else { //字符類型 mTvTitle.setText((CharSequence)title); } } } } /**頁面跳轉(zhuǎn)值傳遞**/ protected void setBundle(Object... objects) { Bundle arguments = new Bundle(); arguments.putSerializable(key, objects); GeneralFragment generalFragment = new GeneralFragment(); generalFragment.setArguments(arguments); } /**獲取所傳遞的值**/ protected Object[] getBundle() { if(getArguments() != null) { System.out.println("getBundle"); if(getArguments().containsKey(key)) { Object[] object = (Object[]) getArguments().getSerializable(key); return object; } } return null; } /**無參頁面跳轉(zhuǎn)**/ protected void toIntent(GeneralFragment generalFragment) { if(generalFragment != null) { getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.general_fragment, generalFragment).commit(); } } }
程序入口MainFragment:
package com.zhf.frameworkdemo02.fragments; import com.zhf.frameworkdemo02.R; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; /** *MainView * @author ZHF * */ public class MainFragment extends FragmentActivity implements BottomFragment.Callbacks { public final static String Item = "item"; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化默認(rèn)調(diào)用接口中item選中方法 onItemSelected(R.id.fragment_bottom_home); } @Override public void onItemSelected(int item) { Bundle arguments = new Bundle(); arguments.putInt(Item, item); //將選中的底部radio的Id放進(jìn)去 GeneralFragment generalFragment = new GeneralFragment(); generalFragment.setArguments(arguments); //設(shè)置參數(shù)值 //這里根據(jù)item的ID進(jìn)行界面跳轉(zhuǎn) FragmentManager fm = getSupportFragmentManager(); fm.beginTransaction().replace(R.id.main_detail_FrameLayout, generalFragment).commit(); } }
說明:這里我們的每個(gè)界面都將采用Fragment,故每個(gè)界面需重寫onCreateView()
package com.zhf.frameworkdemo02.view; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhf.frameworkdemo02.R; import com.zhf.frameworkdemo02.fragments.GeneralFragment; /** * 主頁面 * @author ZHF * */ public class HomeView extends GeneralFragment{ @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); super.setTitle("主頁"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.home, container, false); } }
(其他三個(gè)略)
最終效果圖:
ok!大功告成!相當(dāng)實(shí)用的!有興趣的可以學(xué)習(xí)一下!
×××:http://down.51cto.com/data/1009354
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。