FragmentTabHost实现底部导航

1,009 阅读3分钟

注意

作为每选一个导航按钮,将显示导航对应的内容。这个内容区域需要使用一个容器来表示。必须设定这个容器的id为android:id/tabcontent

工程目录

效果

步骤

1.修改main_activity.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="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
    <android.support.v4.app.FragmentTabHost
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tab_Host"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="0dp"
                android:layout_height="0dp"
                />
        </LinearLayout>
    </android.support.v4.app.FragmentTabHost>


</LinearLayout>

2.新建四个空白的Fragment 分别为AudioFragment、VideoFragment、 NetAudioFragment和NetVideoFragment

3.在strings.xml中定义tab的标题

<resources>
    <string name="app_name">MobilePlayer4</string>
    <string-array name="tab_title">
        <item>本地视频</item>
        <item>本地音乐</item>
        <item>网络视频</item>
        <item>网络音乐</item>
    </string-array>
</resources>

4.定义底部导航栏的图标和文本的布局(我这里给布局取名为item_title该布局在MainActivity中自定义的getEveryView方法中使用)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                
<!--显示底部导航栏的图标-->
    <ImageView
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:id="@+id/icon"
        android:layout_centerHorizontal="true"
        />
        
    <!--显示底部导航栏的文本-->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/title"
        android:layout_below="@id/icon"
        android:layout_centerHorizontal="true"
        android:text="abc"
        android:textSize="12sp"
        android:textColor="@color/tab_title_selector"
        />
</RelativeLayout>

4.定义底部导航某项被选中候标题的样式(我这里在color资源文件中新建一个tab_title_selector.xml)当底部导航栏被选中时标题变为蓝色,默认为灰色

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="@android:color/holo_blue_dark"/>
    <item android:state_pressed="true" android:color="@android:color/holo_blue_dark"/>
    <item android:color="@android:color/darker_gray"/>
</selector>

5.定义各个图标的样式(被选中时显示的图标,默认时的图标),在drawable资源文件新建4个样式文件分别为

rb_audio_selector.xml其中ic_tab_audio_press、ic_tab_audio_press为两个不同的图标
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/ic_tab_audio_press"/>
    <item android:state_checked="true" android:drawable="@drawable/ic_tab_audio_press"/>
    <item android:drawable="@drawable/ic_tab_audio"/>
</selector>
rb_net_audio_selector.xml其中ic_tab_netaudio_press、ic_tab_netaudio_press为两个不同的图标
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/ic_tab_netaudio_press"/>
    <item android:state_checked="true" android:drawable="@drawable/ic_tab_netaudio_press"/>
    <item android:drawable="@drawable/ic_tab_netaudio"/>
</selector>
rb_video_selector.xml其中ic_tab_video_press、ic_tab_video_press为两个不同的图标
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/ic_tab_video_press"/>
    <item android:state_selected="true" android:drawable="@drawable/ic_tab_video_press"/>
    <item android:drawable="@drawable/ic_tab_video"/>
</selector>
rb_net_video_selector.xml其中ic_tab_netvideo_press、ic_tab_netvideo_press为两个不同的图标
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/ic_tab_netvideo_press"/>
    <item android:state_pressed="true" android:drawable="@drawable/ic_tab_netvideo_press"/>
    <item android:drawable="@drawable/ic_tab_netvideo"/>
</selector>

6.MainActivity的代码

public class MainActivity extends AppCompatActivity {

    FragmentTabHost tabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.activity_main);

        tabHost = (FragmentTabHost)findViewById(R.id.tab_Host);


        //获取tab的标题
        String[] titles = getResources().getStringArray(R.array.tab_title);
        //背景图
        int[] icons = new int[]{R.drawable.rb_video_selector,R.drawable.rb_audio_selector,R.drawable.rb_net_video_selector,R.drawable.rb_net_audio_selector};
        
       //这4个fragment为我们第二步中新建的四个fragment
        Class[] classes = new Class[]{VideoFragment.class,AudioFragment.class,NetVideoFragment.class,NetAudioFragment.class};

        //1绑定显示Fragment的容器
        tabHost.setup(this,getSupportFragmentManager(),R.id.content);
        for (int i=0;i<titles.length;i++){
            // 2生成不同的标签,tag相当于标签的名称
            TabHost.TabSpec tmp =  tabHost.newTabSpec(""+i);
            tmp.setIndicator(getEveryView(this,titles,icons,i));
            tabHost.addTab(tmp,classes[i],null);
        }


    }



/**
 * 这个自定义方法会用到item_title布局,作用时返回底部导航栏中的每一个view
 * 该方法在上面setIndicator中被调用
*/ 

    public View getEveryView(Context context, String[] titles, int[] icons, int index){
        LayoutInflater inflater = LayoutInflater.from(context);
        View title_view = inflater.inflate(R.layout.item_title,null);
        TextView title = (TextView) title_view.findViewById(R.id.title);
        ImageView icon = (ImageView)title_view.findViewById(R.id.icon);
        //设置标签的内容
        title.setText(titles[index]);
        icon.setImageResource(icons[index]);
        return  title_view;
    }

}


在写的过程中也发现了一篇关于用FragmentTabHost实现底部导航的[文章]www.cnblogs.com/xqz0618/p/t…