一、常见的底部菜单(底部导航栏)的实现方式

    xiaoxiao2021-03-26  63

    二、FragmentTabHost介绍

     

    如下图所示,整一个底部导航栏是一个FragmentTabHost,里面包含的每一个“小按钮”我们称之为TabSpec,也就是每一个分页。TabSpec里面需要有指示器Indicator,用来指示用户选中了哪一个,里面一般包含一张图片和文字描述。

    三、FragmentTabHost具体实现方法

     

    核心的实现步骤以及注意点有:

    1、所用的Activity必须要继承FragmentActivity,不然项目就会崩溃。

    2、调用FragmentTabHostsetup()方法,设置FragmentManager,以及指定用于装载Fragment的布局容器。

    3、调用FragmentTabHostaddTab()方法添加分页。

    四、代码

     

    要使用FragmentTabHost,首先需要布局中添加进来,这里我们并没有使用官方提供的v4支持包中的FragmentTabHost,而是使用了我们自定义的FragmentTabHost,主要是因为官方提供的FragmentTabHost并没有进行优化,每次都会重新初始化一次Fragment。自定义FragmentTabHost的代码会在附件给出。

    第一个FrameLayout是用于装载Fragment的,第二个Fragment只是官方文档要求我们这样写的而已,官方要求我们将Fragment放在导航栏之下,与我们的需求刚好相反了。

    再仔细看布局文件,主要是通过LinearLayoutweight属性来控制整个竖直方向的分配,具体不再赘述。

    <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 extends BaseActivity {

     

        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() {

     

            //调用setup()方法,设置FragmentManager,以及指定用于装载Fragment的布局容器

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

     

            //新建5个分页,并且添加到List当中,便于管理其中的图标我们使用了selector进行状态选择即选中的时候会变色

            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) {

                //新建5TabSpec,并且设置好它的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已经继承了FragmentActivity了。每一个TabSpecIndicator的布局文件只有一个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进行状态选择的。需要注意的是,这并不是图片,只是颜色,不能放在drawable目录下,而应该放在color目录下。

    转载请注明原文地址: https://ju.6miu.com/read-660708.html

    最新回复(0)