底部導航欄的實現方式

底部導航欄用的比較多,總結一下:

方法一:TabWidget實現

<?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="vertical" >
     <FrameLayout 
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp"
            ></FrameLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <!-- tabStripEnabled屬性去掉底部下劃線與選項卡間的下劃線 -->
        <!-- layout_alignParentBottom屬性即可將其放在底部菜單欄,注意,必須在RelativeLayout裏 -->
        <TabWidget 
            android:id="@android:id/tabs"
            android:tabStripEnabled="false"
            android:background="#6E6E6E"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            ></TabWidget>
       
    </RelativeLayout>

</TabHost>
主要代碼

package com.example.demo1;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;

public class Demo1Activity extends TabActivity {
    /** Called when the activity is first created. */
    private TabHost tabhost;
    private Intent intent1, intent2, intent3, intent4;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tabhost = getTabHost();
        
        intent1 = new Intent(Demo1Activity.this, One.class);
        tabhost.addTab(tabhost.newTabSpec("one")
                .setIndicator("電話",getResources().getDrawable(android.R.drawable.ic_menu_call))
                .setContent(intent1));
        
        intent2 = new Intent(Demo1Activity.this, Two.class);
        tabhost.addTab(tabhost.newTabSpec("two")
                .setIndicator("相機",getResources().getDrawable(android.R.drawable.ic_menu_camera))
                .setContent(intent2));
        
        intent3 = new Intent(Demo1Activity.this, Three.class);
        tabhost.addTab(tabhost.newTabSpec("three")
                .setIndicator("分享",getResources().getDrawable(android.R.drawable.ic_menu_share))
                .setContent(intent3));
        
        intent4 = new Intent(Demo1Activity.this, Four.class);
        tabhost.addTab(tabhost.newTabSpec("four")
                .setIndicator("更多",getResources().getDrawable(android.R.drawable.ic_menu_more))
                .setContent(intent4));
    }
}
方法二:隱藏TabWidget,用RadioGroup實現

通過setCurrentTabByTag來切換不同的選項卡

<?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"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <FrameLayout 
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0.0dip"
            android:layout_weight="1.0"/>
        <TabWidget 
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.0"
            android:visibility="gone"/>
        <RadioGroup
            android:id="@+id/main_tab"
            android:background="@drawable/maintab_toolbar_bg"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:layout_gravity="bottom">
            <RadioButton 
                android:layout_marginTop="2.0dip"
                android:text="@string/main_home"
                android:drawableTop="@drawable/icon_1_n"
                android:id="@+id/radio_button0"
                style="@style/main_tab_bottom"/>
            <RadioButton 
                android:layout_marginTop="2.0dip"
                android:text="@string/main_news"
                android:drawableTop="@drawable/icon_2_n"
                android:id="@+id/radio_button1"
                style="@style/main_tab_bottom"/>
            <RadioButton 
                android:layout_marginTop="2.0dip"
                android:text="@string/main_my_info"
                android:drawableTop="@drawable/icon_3_n"
                android:id="@+id/radio_button2"
                style="@style/main_tab_bottom"/>
            <RadioButton 
                android:layout_marginTop="2.0dip"
                android:text="@string/menu_search"
                android:drawableTop="@drawable/icon_4_n"
                android:id="@+id/radio_button3"
                style="@style/main_tab_bottom"/>
            <RadioButton 
                android:layout_marginTop="2.0dip"
                android:text="@string/more"
                android:drawableTop="@drawable/icon_5_n"
                android:id="@+id/radio_button4"
                style="@style/main_tab_bottom"/>
        </RadioGroup>
    </LinearLayout>
</TabHost>
背景選擇切換
<?xml version="1.0" encoding="UTF-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/home_btn_bg_s" />
    <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/home_btn_bg_s" />
    <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/home_btn_bg_d" />
    <item android:drawable="@drawable/transparent" />
</selector>
dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="bottom_tab_padding_drawable">2.0dip</dimen>
    <dimen name="bottom_tab_padding_up">5.0dip</dimen>
    <dimen name="bottom_tab_font_size">10.0dip</dimen>
</resources>
drawables.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="drawable" name="transparent">#00000000</item>
</resources>
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="main_tab_bottom">
    <item name="android:textSize">@dimen/bottom_tab_font_size</item>
    <item name="android:textColor">#ffffffff</item>
    <item name="android:ellipsize">marquee</item>
    <item name="android:gravity">center_horizontal</item>
    <item name="android:background">@drawable/home_btn_bg</item>
    <item name="android:paddingTop">@dimen/bottom_tab_padding_up</item>
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:button">@null</item>
    <item name="android:singleLine">true</item>
    <item name="android:drawablePadding">@dimen/bottom_tab_padding_drawable</item>
    <item name="android:layout_weight">1.0</item>
</style>
</resources>

主要代碼:

package com.loulijun.demo2;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.RadioGroup.OnCheckedChangeListener;
public class MainTabActivity extends TabActivity implements OnCheckedChangeListener{
    private RadioGroup mainTab;
    private TabHost tabhost;
    private Intent iHome;
    private Intent iNews;
    private Intent iInfo;
    private Intent iSearch;
    private Intent iMore;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        mainTab=(RadioGroup)findViewById(R.id.main_tab);
        mainTab.setOnCheckedChangeListener(this);
        tabhost = getTabHost();
        
        iHome = new Intent(this, HomeActivity.class);
        tabhost.addTab(tabhost.newTabSpec("iHome")
                .setIndicator(getResources().getString(R.string.main_home), getResources().getDrawable(R.drawable.icon_1_n))
                .setContent(iHome));
        
        iNews = new Intent(this, NewsActivity.class);
        tabhost.addTab(tabhost.newTabSpec("iNews")
                .setIndicator(getResources().getString(R.string.main_news), getResources().getDrawable(R.drawable.icon_2_n))
                .setContent(iNews));
        
        iInfo = new Intent(this, MyInfoActivity.class);
        tabhost.addTab(tabhost.newTabSpec("iInfo")
                .setIndicator(getResources().getString(R.string.main_my_info), getResources().getDrawable(R.drawable.icon_3_n))
                .setContent(iInfo));
        
        iSearch = new Intent(this,SearchActivity.class);
        tabhost.addTab(tabhost.newTabSpec("iSearch")
                .setIndicator(getResources().getString(R.string.menu_search), getResources().getDrawable(R.drawable.icon_4_n))
                .setContent(iSearch));
        
        iMore = new Intent(this, MoreActivity.class);
         tabhost.addTab(tabhost.newTabSpec("iMore")
                    .setIndicator(getResources().getString(R.string.more), getResources().getDrawable(R.drawable.icon_5_n))
                    .setContent(iMore));
    }
   

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch(checkedId){
        case R.id.radio_button0:
            this.tabhost.setCurrentTabByTag("iHome");
            break;
        case R.id.radio_button1:
            this.tabhost.setCurrentTabByTag("iNews");
            break;
        case R.id.radio_button2:
            this.tabhost.setCurrentTabByTag("iInfo");
            break;
        case R.id.radio_button3:
            this.tabhost.setCurrentTabByTag("iSearch");
            break;
        case R.id.radio_button4:
            this.tabhost.setCurrentTabByTag("iMore");
            break;
        }
    }
    
    
}

方法三:Fragment+FragmentTabhost

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:background="#E6E8ED"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#1B9EE2"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/command_select_common_back_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:background="#00000000"
            android:drawableLeft="@drawable/v360_common_back"
            android:paddingRight="5dp"
            android:text="派車單查詢" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        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="@drawable/bg_tabhost_bg" >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

主要代碼

public class CommandSelectActivity extends FragmentActivity implements OnClickListener{

	private FragmentTabHost mTabHost;
	private LayoutInflater mLayoutInflater;
	private Class mFragmentArray[] = { CommandSelectHostoryFragment.class, CommandSelectIncompleteFragment.class };
	
	//tab_home_btn, tab_message_btn 爲暫用的兩個圖標,顯示在查詢類按鈕
	private int mImageArray[] = { R.drawable.tab_home_btn, R.drawable.tab_message_btn};
	private String mTextArray[] = { "歷史派車單查詢", "未完成派車單查詢" };

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.command_select);

		initView();
		
		findViewById(R.id.command_select_common_back_button).setOnClickListener(this);
	}

	private void initView() {
		mLayoutInflater = LayoutInflater.from(this);

		mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
		mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
		int count = mFragmentArray.length;
		for (int i = 0; i < count; i++) {
			TabSpec tabSpec = mTabHost.newTabSpec(mTextArray[i]).setIndicator(getTabItemView(i));
			mTabHost.addTab(tabSpec, mFragmentArray[i], null);
			mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.selector_tab_background);
		}
	}

	private View getTabItemView(int index) {
		View view = mLayoutInflater.inflate(R.layout.command_select_itemview, null);
		ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
		imageView.setImageResource(mImageArray[index]);
		TextView textView = (TextView) view.findViewById(R.id.textview);
		textView.setText(mTextArray[index]);

		return view;
	}

	@Override
	public void onClick(View view) {
		if(view.getId() == R.id.command_select_common_back_button){
			finish();
		}
	}
	
}

方法四:ViewPager 可滑動

package com.wisdom.viewpager;

import java.util.ArrayList;
import com.wisdom.main.BaseActivity;
import com.wisdom.main.R;
import com.wisdom.model.BottomViewItem;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ViewPagerActivity extends BaseActivity implements OnClickListener, OnPageChangeListener {

        ViewPager viewPager;
        ViewPagerAdapter viewAdapter;
        BottomViewItem item;
        ArrayList<View> mViewItems = new ArrayList<View>();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.viewpager_layout);
                item = BottomViewItem.getInstance();
                initViews();
                setTabSelection(0);
        }

        /**
         * 控件初始化
         */
        private void initViews() {
                viewPager = (ViewPager) findViewById(R.id.main_viewpager);
                for (int i = 0; i < item.viewNum; i++) {
                        mViewItems.add(getLayoutInflater().inflate(item.layouts_id[i], null));
                }
                viewAdapter = new ViewPagerAdapter(this, mViewItems);
                viewPager.setAdapter(viewAdapter);
                viewPager.setOnPageChangeListener(this);
                for (int i = 0; i < item.viewNum; i++) {
                        item.linears[i] = (LinearLayout) findViewById(item.linears_id[i]);
                        item.linears[i].setOnClickListener(this);
                        item.images[i] = (ImageView) findViewById(item.images_id[i]);
                        item.texts[i] = (TextView) findViewById(item.texts_id[i]);
                }
        }

        /**
         * @param index
         *            根據索引值切換fragment
         */
        private void setTabSelection(int index) {
                clearSelection();
                item.images[index].setImageResource(item.images_selected[index]);
                item.texts[index].setTextColor(getResources().getColor(R.color.bottom_text_selected));
        }

        /**
         * 清空所有圖標和文字狀態
         */
        private void clearSelection() {
                for (int i = 0; i < item.viewNum; i++) {
                        item.images[i].setImageResource(item.images_unselected[i]);
                        item.texts[i].setTextColor(getResources().getColor(R.color.bottom_text_unselected));
                }
        }

        @Override
        public void onClick(View v) {
                for (int i = 0; i < item.linears_id.length; i++)
                        if (v.getId() == item.linears_id[i]) {
                                viewPager.setCurrentItem(i);
                                setTabSelection(i);
                        }
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int arg0) {
                setTabSelection(arg0);
        }
}

package com.wisdom.viewpager;

import java.util.ArrayList;

import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

public class ViewPagerAdapter extends PagerAdapter {

        /**
         * 保存當前activity引用
         */
        private ViewPagerActivity mContext;
        /**
         * 保存當前所有頁面
         */
        private ArrayList<View> mViewItems;
        /**
         * 當前頁面的佈局
         */
        private View convertView;

        public ViewPagerAdapter(ViewPagerActivity context, ArrayList<View> viewItems) {
                mContext = context;
                mViewItems = viewItems;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(mViewItems.get(position));
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
                convertView = mViewItems.get(position);
                // 此處自定義頁面數據處理
                container.addView(mViewItems.get(position));
                return mViewItems.get(position);
        }

        @Override
        public int getCount() {
                if (mViewItems == null || mViewItems.size() == 0)
                        return 1;
                return mViewItems.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
                return arg0 == arg1;
        }

}

方法五:自定義View

可擴展性、適應性強

  1、主BaseView.java
       此類爲點擊底部菜單切換頁面View的父類,用於實現不同的佈局頁面和相關頁面操作。

package com.wisdom.btten;

import android.app.Activity;
import android.view.View;

public class BaseView {

        protected Activity mContext;
        protected View view;
        public static BttenTabbar mTab;

        public BaseView(Activity context, int layoutId, BttenTabbar tab) {
                mContext = context;
                mTab = tab;
                view = mContext.getLayoutInflater().inflate(layoutId, null);
                view.setTag(this);
        }

        /**
         * [url=home.php?mod=space&uid=7300]@return[/url] 返回真實的view
         */
        public View getView() {
                return view;
        }

        /**
         * @return 返回容器
         */
        public BttenTabbar getTab() {
                return mTab;
        }

        /**
         * 進入view時觸發
         */
        public void OnViewShow() {

        };

        /**
         * 退出view時觸發
         */
        public void OnViewHide() {

        };
}

2、BttenTabbar.java
        此類爲主要底部菜單欄的構造類,也包括實現了按鈕點擊、文字變色、圖片切換背景等特效邏輯。

package com.wisdom.btten;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.wisdom.main.R;
import com.wisdom.model.BottomViewItem;

public class BttenTabbar implements IViewFactory, OnClickListener {

        /**
         * 用於保存當前activity
         */
        BttenActivity mContext;
        /**
         * 當前頁面焦點,即顯示的頁面索引
         */
        int mCurrentFocus = -1;
        /**
         * 切換頁面時上一個view的索引
         */
        int lastIndex = -1;
        /**
         * 底部菜單欄初始化所有控件類的一個實例
         */
        BottomViewItem item;

        /**
         * 存放view的佈局容器
         */
        ViewContainer viewContainer;

        /**
         * 首次創建頁面的臨時view
         */
        public BaseView newView;

        public BttenTabbar(BttenActivity context) {
                mContext = context;
                item = BottomViewItem.getInstance();
                initTab();
        }

        /**
         * 控件初始化
         */
        private void initTab() {
                for (int i = 0; i < item.viewNum; i++) {
                        item.linears[i] = (LinearLayout) mContext.findViewById(item.linears_id[i]);
                        item.linears[i].setOnClickListener(this);
                        item.images[i] = (ImageView) mContext.findViewById(item.images_id[i]);
                        item.texts[i] = (TextView) mContext.findViewById(item.texts_id[i]);
                }
                viewContainer = (ViewContainer) mContext.findViewById(R.id.main_view_container);
                viewContainer.setViewFactory(this);
                switchViewTab(0);
        }

        /**
         * @param index
         *            根據索引值切換view
         */
        public void switchViewTab(int index) {
                if (index == mCurrentFocus)
                        return;
                setViewTab(index);
                viewContainer.flipToView(index);
        }

        /**
         * @param index
         *            根據索引值切換背景
         */
        private void setViewTab(int index) {
                if (index == mCurrentFocus)
                        return;
                lastIndex = mCurrentFocus;
                mCurrentFocus = index;
                for (int i = 0; i < item.viewNum; i++) {
                        item.images[i].setBackgroundResource(i == index ? item.images_selected[i] : item.images_unselected[i]);
                        item.texts[i].setTextColor(i == index ? mContext.getResources().getColor(R.color.bottom_text_selected) : mContext.getResources().getColor(R.color.bottom_text_unselected));
                }
        }

        @Override
        public void onClick(View v) {
                for (int i = 0; i < item.viewNum; i++) {
                        if (v.getId() == item.linears_id[i]) {
                                switchViewTab(i);
                        }
                }
        }

        @Override
        public View createView(int index) {
                newView = new BaseView(mContext, item.layouts_id[index], this);
                return newView.getView();
        }
}

 3、ViewContainer.java
       此類爲一個父容器,用於存放不用頁面的佈局View,簡單的做了些緩存機制的邏輯。

package com.wisdom.btten;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

public class ViewContainer extends FrameLayout {

        IViewFactory mViewFactory;
        private View tempView = null;
        private View currentView = null;
        private BaseView baseView = null;
        private Map<Integer, View> viewMap = null;
        private int cuIndex;
        LayoutParams newLayout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        public ViewContainer(Context context) {
                super(context);
                init();
        }

        public ViewContainer(Context context, AttributeSet attrs) {
                super(context, attrs);
                init();
        }

        public ViewContainer(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
                init();
        }

        private void init() {
                viewMap = new HashMap<Integer, View>();
                cuIndex = -1;
        }

        public void setViewFactory(IViewFactory viewFactory) {
                mViewFactory = viewFactory;
        }

        public View getCurrentView() {
                return currentView;
        }

        public void flipToView(int index) {
                if (index == cuIndex)
                        return;
                if (viewMap.containsKey(index)) {
                        tempView = viewMap.get(index);
                        setViewState();
                        return;
                }
                tempView = mViewFactory.createView(index);
                viewMap.put(index, tempView);
                this.addView(tempView, newLayout);
                setViewState();
        }

        private void setViewState() {
                if (currentView != null) {
                        baseView = (BaseView) currentView.getTag();
                        currentView.setVisibility(View.GONE);
                        baseView.OnViewHide();
                }
                baseView = (BaseView) tempView.getTag();
                tempView.setVisibility(View.VISIBLE);
                baseView.OnViewShow();

                currentView = tempView;
        }
}

 4、IViewFactory.java
       這是一個工廠構造接口,用於創建個頁面佈局View。

package com.wisdom.btten;

import android.view.View;

public interface IViewFactory {
        View createView(int index);
}

5、BttenActivity.java
       
頁面展示主類文件,用於初始化頁面。

package com.wisdom.btten;

import com.wisdom.main.BaseActivity;
import com.wisdom.main.R;
import android.os.Bundle;

public class BttenActivity extends BaseActivity {

        BttenTabbar tabbar;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.btten_layout);
                tabbar = new BttenTabbar(this);
        }

}

參考鏈接:http://www.cnblogs.com/loulijun/archive/2012/03/21/2409994.html

http://www.eoeandroid.com/forum.php?mod=viewthread&tid=497478

發佈了36 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章