【Android UI设计与开发】5.底部菜单栏(二)使用Fragment实现底部菜单栏

既然 Fragment 取代了TabActivity,当然 TabActivity 的能实现的菜单栏,Fragment 当然也能实现。主要其实就是通过菜单栏的点击事件切换 Fragment 的显示和隐藏。

来看看栗子吧:

1.效果图来了:

【Android UI设计与开发】5.底部菜单栏(二)使用Fragment实现底部菜单栏

 

2.代码具体实现

2.1 自定义底部菜单栏实现方式

(1)对应的 Fragment 编辑代码和布局实现在前面的 Fragment介绍和简单实现  中已经有提及,代码中没复杂的地方,此处略过,具体可看实例代码。

(2)菜单栏实现,这里使用代码实现的,其实也可以用布局文件实现,代码如下:

【Android UI设计与开发】5.底部菜单栏(二)使用Fragment实现底部菜单栏
package com.yanis.yc_ui_fragment_menu;



import android.content.Context;

import android.graphics.Color;

import android.util.AttributeSet;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;



/**

 * 

 * @author YeChao

 * @功能描述:自定义底部工具栏

 *

 */

public class ViewIndicator extends LinearLayout implements OnClickListener {

    private int mDefaultIndicator = 0; // 默认的选定View



    private static int mCurIndicator; // 当前选定View



    private static View[] mIndicators; // View集合



    private OnIndicateListener mOnIndicateListener; // 对应的监听器

    // 对应的图标Tag

    private static final String TAG_ICON_0 = "icon_tag_0";

    private static final String TAG_ICON_1 = "icon_tag_1";

    private static final String TAG_ICON_2 = "icon_tag_2";

    private static final String TAG_ICON_3 = "icon_tag_3";

    private static final String TAG_ICON_4 = "icon_tag_4";

    // 对应的文字Tag

    private static final String TAG_TEXT_0 = "text_tag_0";

    private static final String TAG_TEXT_1 = "text_tag_1";

    private static final String TAG_TEXT_2 = "text_tag_2";

    private static final String TAG_TEXT_3 = "text_tag_3";

    private static final String TAG_TEXT_4 = "text_tag_4";

    // 未选中状态

    private static final int COLOR_UNSELECT = Color.argb(100, 0xff, 0xff, 0xff);

    // 选中状态

    private static final int COLOR_SELECT = Color.WHITE;



    // 构造函数

    public ViewIndicator(Context context) {

        super(context);

    }



    public ViewIndicator(Context context, AttributeSet attrs) {

        super(context, attrs);

        mCurIndicator = mDefaultIndicator;

        setOrientation(LinearLayout.HORIZONTAL);// 水平布局

        init();

    }



    /**

     * 菜单视图布局

     * 

     * @param iconResID

     *            图片资源ID

     * @param stringResID

     *            文字资源ID

     * @param stringColor

     *            颜色资源ID

     * @param iconTag

     *            图片标签

     * @param textTag

     *            文字标签

     * @return

     */

    private View createIndicator(int iconResID, int stringResID,

            int stringColor, String iconTag, String textTag) {

        // 实例一个LinearLayout

        LinearLayout view = new LinearLayout(getContext());

        view.setOrientation(LinearLayout.VERTICAL);// 垂直布局

        // 设置宽高和权重

        view.setLayoutParams(new LinearLayout.LayoutParams(

                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));

        view.setGravity(Gravity.CENTER_HORIZONTAL);

        view.setBackgroundResource(R.drawable.main_tab_item_bg_normal);

        // 实例一个ImageView

        ImageView iconView = new ImageView(getContext());

        // 设置与该ImageView视图相关联的标记

        iconView.setTag(iconTag);

        // 设置宽高和权重

        iconView.setLayoutParams(new LinearLayout.LayoutParams(

                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));

        iconView.setImageResource(iconResID);// 设置图片资源

        // 实例一个TextView

        TextView textView = new TextView(getContext());

        // 设置与该TextView视图相关联的标记

        textView.setTag(textTag);

        // 设置宽高和权重

        textView.setLayoutParams(new LinearLayout.LayoutParams(

                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));

        // 设置文字颜色

        textView.setTextColor(stringColor);

        // 设置文字大小

        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);

        // 设置文字资源

        textView.setText(stringResID);

        // 添加视图到布局中

        view.addView(iconView);

        view.addView(textView);

        // 返回布局视图

        return view;



    }



    /**

     * 初始化视图

     */

    private void init() {

        mIndicators = new View[5];// 5个View

        // 第一个为默认选中的

        // 主页main_tab_item_bg_normal

        mIndicators[0] = createIndicator(R.drawable.main_tab_item_home_focus,

                R.string.tab_item_home, COLOR_SELECT, TAG_ICON_0, TAG_TEXT_0);

        mIndicators[0].setBackgroundResource(R.drawable.main_tab_item_bg);

        mIndicators[0].setTag(Integer.valueOf(0));

        mIndicators[0].setOnClickListener(this);

        addView(mIndicators[0]);

        // 分类

        mIndicators[1] = createIndicator(

                R.drawable.main_tab_item_category_normal,

                R.string.tab_item_category, COLOR_UNSELECT, TAG_ICON_1,

                TAG_TEXT_1);

        mIndicators[1].setBackgroundResource(R.drawable.main_tab_item_bg);

        mIndicators[1].setTag(Integer.valueOf(1));

        mIndicators[1].setOnClickListener(this);

        addView(mIndicators[1]);

        // 下载

        mIndicators[2] = createIndicator(R.drawable.main_tab_item_down_normal,

                R.string.tab_item_down, COLOR_UNSELECT, TAG_ICON_2, TAG_TEXT_2);

        mIndicators[2].setBackgroundResource(R.drawable.main_tab_item_bg);

        mIndicators[2].setTag(Integer.valueOf(2));

        mIndicators[2].setOnClickListener(this);

        addView(mIndicators[2]);

        // 我的

        mIndicators[3] = createIndicator(R.drawable.main_tab_item_user_normal,

                R.string.tab_item_user, COLOR_UNSELECT, TAG_ICON_3, TAG_TEXT_3);

        mIndicators[3].setBackgroundResource(R.drawable.main_tab_item_bg);

        mIndicators[3].setTag(Integer.valueOf(3));

        mIndicators[3].setOnClickListener(this);

        addView(mIndicators[3]);

        // 设置

        mIndicators[4] = createIndicator(

                R.drawable.main_tab_item_setting_normal,

                R.string.tab_item_setting, COLOR_UNSELECT, TAG_ICON_4,

                TAG_TEXT_4);

        mIndicators[4].setBackgroundResource(R.drawable.main_tab_item_bg);

        mIndicators[4].setTag(Integer.valueOf(4));

        mIndicators[4].setOnClickListener(this);

        addView(mIndicators[4]);

    }



    public static void setIndicator(int which) {

        // /////////////////清除之前的状态/////////////////////////////////

        // mIndicators[mCurIndicator].setBackgroundResource(R.drawable.main_tab_item_bg_normal);

        ImageView prevIcon;

        TextView prevText;

        switch (mCurIndicator) {

        case 0:

            prevIcon = (ImageView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_ICON_0);

            prevIcon.setImageResource(R.drawable.main_tab_item_home);

            prevText = (TextView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_TEXT_0);

            prevText.setTextColor(COLOR_UNSELECT);

            break;

        case 1:

            prevIcon = (ImageView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_ICON_1);

            prevIcon.setImageResource(R.drawable.main_tab_item_category);

            prevText = (TextView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_TEXT_1);

            prevText.setTextColor(COLOR_UNSELECT);

            break;

        case 2:

            prevIcon = (ImageView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_ICON_2);

            prevIcon.setImageResource(R.drawable.main_tab_item_down);

            prevText = (TextView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_TEXT_2);

            prevText.setTextColor(COLOR_UNSELECT);

            break;

        case 3:

            prevIcon = (ImageView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_ICON_3);

            prevIcon.setImageResource(R.drawable.main_tab_item_user);

            prevText = (TextView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_TEXT_3);

            prevText.setTextColor(COLOR_UNSELECT);

            break;

        case 4:

            prevIcon = (ImageView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_ICON_4);

            prevIcon.setImageResource(R.drawable.main_tab_item_setting);

            prevText = (TextView) mIndicators[mCurIndicator]

                    .findViewWithTag(TAG_TEXT_4);

            prevText.setTextColor(COLOR_UNSELECT);

            break;

        }

        // /////////////////更新前状态/////////////////////////////////

        // mIndicators[which].setBackgroundResource(R.drawable.main_tab_item_bg_focus);

        ImageView currIcon;

        TextView currText;

        /**

         * 设置选中状态

         */

        switch (which) {

        case 0:

            currIcon = (ImageView) mIndicators[which]

                    .findViewWithTag(TAG_ICON_0);

            currIcon.setImageResource(R.drawable.main_tab_item_home_focus);

            currText = (TextView) mIndicators[which]

                    .findViewWithTag(TAG_TEXT_0);

            currText.setTextColor(COLOR_SELECT);

            break;

        case 1:

            currIcon = (ImageView) mIndicators[which]

                    .findViewWithTag(TAG_ICON_1);

            currIcon.setImageResource(R.drawable.main_tab_item_category_focus);

            currText = (TextView) mIndicators[which]

                    .findViewWithTag(TAG_TEXT_1);

            currText.setTextColor(COLOR_SELECT);

            break;

        case 2:

            currIcon = (ImageView) mIndicators[which]

                    .findViewWithTag(TAG_ICON_2);

            currIcon.setImageResource(R.drawable.main_tab_item_down_focus);

            currText = (TextView) mIndicators[which]

                    .findViewWithTag(TAG_TEXT_2);

            currText.setTextColor(COLOR_SELECT);

            break;

        case 3:

            currIcon = (ImageView) mIndicators[which]

                    .findViewWithTag(TAG_ICON_3);

            currIcon.setImageResource(R.drawable.main_tab_item_user_focus);

            currText = (TextView) mIndicators[which]

                    .findViewWithTag(TAG_TEXT_3);

            currText.setTextColor(COLOR_SELECT);

            break;

        case 4:

            currIcon = (ImageView) mIndicators[which]

                    .findViewWithTag(TAG_ICON_4);

            currIcon.setImageResource(R.drawable.main_tab_item_setting_focus);

            currText = (TextView) mIndicators[which]

                    .findViewWithTag(TAG_TEXT_4);

            currText.setTextColor(COLOR_SELECT);

            break;

        }



        mCurIndicator = which;

    }



    public interface OnIndicateListener {

        public void onIndicate(View v, int which);

    }



    public void setOnIndicateListener(OnIndicateListener listener) {

        mOnIndicateListener = listener;

    }



    @Override

    public void onClick(View v) {

        if (mOnIndicateListener != null) {

            int tag = (Integer) v.getTag();

            switch (tag) {

            case 0:

                if (mCurIndicator != 0) {

                    mOnIndicateListener.onIndicate(v, 0);

                    setIndicator(0);

                }

                break;

            case 1:

                if (mCurIndicator != 1) {

                    mOnIndicateListener.onIndicate(v, 1);

                    setIndicator(1);

                }

                break;

            case 2:

                if (mCurIndicator != 2) {

                    mOnIndicateListener.onIndicate(v, 2);

                    setIndicator(2);

                }

                break;

            case 3:

                if (mCurIndicator != 3) {

                    mOnIndicateListener.onIndicate(v, 3);

                    setIndicator(3);

                }

                break;

            case 4:

                if (mCurIndicator != 4) {

                    mOnIndicateListener.onIndicate(v, 4);

                    setIndicator(4);

                }

                break;

            default:

                break;

            }

        }

    }

}
ViewIndicator

(3)最后就是主界面代码,切换 Fragment 的显示和隐藏以及菜单栏的选中状态

package com.yanis.yc_ui_fragment_menu;



import com.yanis.yc_ui_fragment_menu.ViewIndicator.OnIndicateListener;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentActivity;

import android.view.View;



public class MainActivity extends FragmentActivity {

     public static Fragment[] mFragments;  

     

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        

        setFragmentIndicator(0);  

    }

    

     /** 

     * 初始化fragment 

     */  

    private void setFragmentIndicator(int whichIsDefault) { 

        //实例化 Fragment 集合

         mFragments = new Fragment[5];  

         mFragments[0] = getSupportFragmentManager().findFragmentById(R.id.fragment_home);  

         mFragments[1] = getSupportFragmentManager().findFragmentById(R.id.fragment_category);  

         mFragments[2] = getSupportFragmentManager().findFragmentById(R.id.fragment_down);  

         mFragments[3] = getSupportFragmentManager().findFragmentById(R.id.fragment_user);  

         mFragments[4] = getSupportFragmentManager().findFragmentById(R.id.fragment_setting);  

         //显示默认的Fragment

         getSupportFragmentManager().beginTransaction().hide(mFragments[0]) .hide(mFragments[1]).hide(mFragments[2]).hide(mFragments[3]).hide(mFragments[4]).show(mFragments[whichIsDefault]).commit(); //绑定自定义的菜单栏组件

        ViewIndicator mIndicator = (ViewIndicator) findViewById(R.id.indicator);  

        ViewIndicator.setIndicator(whichIsDefault);  

        mIndicator.setOnIndicateListener(new OnIndicateListener() {  

            @Override  

            public void onIndicate(View v, int which) {  

                //显示指定的Fragment

                  getSupportFragmentManager().beginTransaction()  

                  .hide(mFragments[0]).hide(mFragments[1])  

                  .hide(mFragments[2]).hide(mFragments[3]).hide(mFragments[4]).show(mFragments[which]).commit(); 

            }  

        });  

    }  

}

 

源代码地址:https://github.com/YeXiaoChao/Yc_ui_fragment_menu

 


 

 

2.2 使用 Fragment+FragmentTabHost 来实现底部菜单栏方式

效果是一样的,只是在上面的基础上使用 FragmentTabHost 来实现底部菜单栏,直接通过 FragmentTabHost 来切换 Fragment 的显示 ,而不是自定义的布局。

(1)修改主布局代码,加入了FragmentTabHost 组件

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >



    <FrameLayout

        android:id="@+id/realtabcontent"

        android:layout_width="fill_parent"

        android:layout_height="0dip"

        android:layout_weight="1" />



    <android.support.v4.app.FragmentTabHost

        android:id="@android:id/tabhost"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content" 

        android:background="@drawable/main_tab_item_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>

(2)单独为Tab按钮选项布局

<?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/imageview"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:focusable="false"

        android:padding="3dp" 

        android:src="@drawable/main_tab_item_home">

    </ImageView>



    <TextView

        android:id="@+id/textview"       

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" 

        android:textSize="12sp"

        android:textColor="#ffffff">

    </TextView>



</LinearLayout>

(3) fragment布局界面和之前一样,就不再赘述

(4) Tab选项的自定义按钮中图片资源文件,列出其中一个按钮,指定了按钮的选中状态和不选中状态不同的图片显示

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">



    <item android:drawable="@drawable/main_tab_item_home_focus" android:state_selected="true"/>

    <item android:drawable="@drawable/main_tab_item_home_normal"/>



</selector>

(5) Tab选项按钮背景资源文件,指定了点击的效果

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">



    <!-- pressed -->

    <item android:drawable="@drawable/main_tab_item_bg_focus" android:state_enabled="true" android:state_pressed="true"/>



    <!-- focused -->

    <item android:drawable="@drawable/main_tab_item_bg_focus" android:state_enabled="true" android:state_focused="true"/>



    <!-- normal -->

    <item android:drawable="@drawable/main_tab_item_bg_normal" android:state_enabled="true"/>



</selector>

(6) 最后就是主界面代码的改变

package com.yanis.yc_ui_fragment_tabhost;



import android.os.Bundle;

import android.support.v4.app.FragmentActivity;

import android.support.v4.app.FragmentTabHost;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.ImageView;

import android.widget.TabHost.TabSpec;

import android.widget.TextView;



/**

 * 

 * @author yechao

 * @功能说明 自定义TabHost

 *

 */

public class MainActivity extends FragmentActivity {

    // 定义FragmentTabHost对象

    private FragmentTabHost mTabHost;



    // 定义一个布局

    private LayoutInflater layoutInflater;



    // 定义数组来存放Fragment界面

    private Class fragmentArray[] = { FragmentHome.class,

            FragmentCategory.class, FragmentDown.class, FragmentUser.class,

            FragmentSetting.class };



    // 定义数组来存放按钮图片

    private int mImageViewArray[] = { R.drawable.main_tab_item_home,

            R.drawable.main_tab_item_category, R.drawable.main_tab_item_down,

            R.drawable.main_tab_item_user, R.drawable.main_tab_item_setting };



    // Tab选项卡的文字

    private String mTextviewArray[] = { "主页", "分类", "下载", "我的", "设置" };



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);



        initView();

    }



    /**

     * 初始化组件

     */

    private void initView() {

        // 实例化布局对象

        layoutInflater = LayoutInflater.from(this);



        // 实例化TabHost对象,得到TabHost

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);

        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);



        // 得到fragment的个数

        int count = fragmentArray.length;



        for (int i = 0; i < count; i++) {

            // 为每一个Tab按钮设置图标、文字和内容

            TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i])

                    .setIndicator(getTabItemView(i));

            // 将Tab按钮添加进Tab选项卡中

            mTabHost.addTab(tabSpec, fragmentArray[i], null);

            // 设置Tab按钮的背景

            mTabHost.getTabWidget().getChildAt(i)

                    .setBackgroundResource(R.drawable.main_tab_item_bg);

        }

    }



    /**

     * 给Tab按钮设置图标和文字

     */

    private View getTabItemView(int index) {

        View view = layoutInflater.inflate(R.layout.tab_item_view, null);



        ImageView imageView = (ImageView) view.findViewById(R.id.imageview);

        imageView.setImageResource(mImageViewArray[index]);



        TextView textView = (TextView) view.findViewById(R.id.textview);

        textView.setText(mTextviewArray[index]);



        return view;

    }

}

 

源代码地址:https://github.com/YeXiaoChao/Yc_ui_fragment_tabhost

你可能感兴趣的:(android ui)