其他分享
首页 > 其他分享> > 安卓底部导航栏

安卓底部导航栏

作者:互联网

FrameLayout+碎片实现底部导航

一、效果展示(若觉得画面太大,可单击后观看)

二、底部导航栏布局

1、 新建bottom.xml文件

2、设置布局:

3、代码:

<?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="58dp"
    android:background="@android:color/background_light"
    android:gravity="center">

    <LinearLayout
        android:id="@+id/id_tab_home"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_home_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_home_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:text="首页" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_video"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_video_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_video_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:text="视频" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_social"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_social_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_social_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:text="社交" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_mine"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_mine_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_mine_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:text="我的" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_setting"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_settings_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/settings_norm" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:text="设置" />
    </LinearLayout>

</LinearLayout>

三、准备导航碎片

1、创建5个碎片,分别为Home、Video、Mine、Social、Settings

2、分别修改Home.java、Video.java、Mine.java、Social.java、Settings.java文件

​ (1)Home.java


 public class Home extends Fragment {


    public Home() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_home, container, false);
    }

}

​ (2)Video.java

public class Video extends Fragment {


    public Video()
    {
        //需要一个空的公共构造函数,作为实例的一个创建
    }

//当Fragment创建视图时调用onCreateView()生命周期方法
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    //LayoutInflater的作用类似于findViewById(),不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;
    // 而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。
    // 具体作用:1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
    //         2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素

    {
        // 用碎片填充布局
        return inflater.inflate(R.layout.activity_video, container, false);
    }

}

​ (3)Mine.java

public class Mine extends Fragment {


    public Mine() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_mine, container, false);
    }

}

​ (4)Social.java

public class Social extends Fragment 
{


    public Social() 
    {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_social, container, false);
    }
}

​ (5)Settings.java

public class Settings extends Fragment {


    public Settings()
    {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_settings, container, false);
    }
}

3、分别修改activity_home.xml、activity_video.xml、activity_mine.xml、 activity_social.xml、activity_settings.xml文件

(1)activity_home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@drawable/home"

    tools:context=".Home">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       android:layout_marginTop="160dp"
        android:layout_marginLeft="50dp"
        android:textSize="50sp"
        android:textStyle="italic"
        android:textColor="@color/plum"
        android:text="欢迎来到首页" />

</FrameLayout>

(2)activity_video.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@drawable/vedio"
    tools:context=".Video">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="40sp"
        android:textStyle="italic"
        android:textColor="@color/blue"
        android:text="观看兔兔视频" />

</FrameLayout>

(3)activity_mine.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@drawable/mine"
    tools:context=".Mine">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="180dp"
        android:layout_marginLeft="60dp"
        android:textSize="30sp"
        android:textStyle="italic"
        android:textColor="@color/plum"
        android:text="这是属于自己的空间哦" />

</FrameLayout>

(4)activity_social.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@drawable/social"
    tools:context=".Social">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="100dp"
        android:layout_marginLeft="60dp"
        android:textSize="30sp"
        android:textStyle="italic"
        android:textColor="@color/teal_200"
        android:text="来认识更多朋友吧" />

</FrameLayout>

(5)activity_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Settings">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/settings"
        android:orientation="vertical">

        <Button
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="45dp"
            android:layout_marginTop="110dp"
            android:background="@drawable/shape_round"
            android:hint="隐私设置"
            android:textColorHint="@color/plum"
            android:textSize="20sp" />

        <Button
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="100dp"
            android:background="@drawable/shape_round"
            android:hint="通用设置"
            android:textColorHint="@color/plum"
            android:textSize="20sp" />

        <Button
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="100dp"
            android:background="@drawable/shape_round"
            android:hint="用户设置"
            android:textColorHint="@color/plum"
            android:textSize="20sp" />

    </LinearLayout>

</FrameLayout>

四、修改MainActivity.java

1、声明变量

public class MainActivity extends AppCompatActivity 
{
    //装载Fragment的集合
    private List<Fragment> mFragments;

    //5个Tab对应的布局
    private LinearLayout mTabHome;
    private LinearLayout mTabVideo;
    private LinearLayout mTabSocial;
    private LinearLayout mTabMine;
    private  LinearLayout mTabSetting;

    //5个Tab对应的ImageButton
    private ImageButton mImgHome;
    private ImageButton mImgVideo;
    private ImageButton mImgSocial;
    private ImageButton mImgMine;
    private ImageButton mImgSettings;
    …………
}

2、初始化onCreate()方法,并设置首次运行时显示的碎片

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initViews();    //初始化控件
    initEvents();     //初始化事件
    initFragments();  //初始化数据
    //initFirstRun(0); 第一次运行初始化界面,显示第一个碎片,本案例中注释此行代码,先显示main页面,不直                        //接显示碎片,点击导航栏才显示
}

3、初始化碎片列表,设置initFragments ()方法

    //初始化碎片集,每个底部导航按钮对应一个碎片
    private void initFragments()
    {
        mFragments = new ArrayList<>();
        //将5个Fragment加入集合中
        mFragments.add(new Home());
        mFragments.add(new Video());
        mFragments.add(new Social());
        mFragments.add(new Mine());
        mFragments.add(new Settings());
    }

4、设置initViews()方法, 初始化控件引用

/*初始化控件*/
private void initViews()
{
    FrameLayout frag_layout = (FrameLayout) findViewById(R.id.frag_layout);

    mTabHome = (LinearLayout) findViewById(R.id.id_tab_home);
    mTabVideo = (LinearLayout) findViewById(R.id.id_tab_video);
    mTabSocial = (LinearLayout) findViewById(R.id.id_tab_social);
    mTabMine = (LinearLayout) findViewById(R.id.id_tab_mine);
    mTabSettings = (LinearLayout) findViewById(R.id.id_tab_settings);

    mImgHome = (ImageButton) findViewById(R.id.id_tab_home_img);
    mImgVideo = (ImageButton) findViewById(R.id.id_tab_video_img);
    mImgSocial = (ImageButton) findViewById(R.id.id_tab_social_img);
    mImgMine = (ImageButton) findViewById(R.id.id_tab_mine_img);
    mImgSettings = (ImageButton) findViewById(R.id.id_tab_settings_img);
}

5、设置initEvents()方法, 初始化事件

(1)为底部导航的每组控件设置监听事件,包括设置ImageButton,以及与当前单击的Tab对应的碎片。

/*设置四个底部导航键的的点击事件*/
private void initEvents() 
{
    mTabHome.setOnClickListener(onClickListener);
    mTabVideo.setOnClickListener(onClickListener);
    mTabSocial.setOnClickListener(onClickListener);
    mTabMine.setOnClickListener(onClickListener);
    mTabSettings.setOnClickListener(onClickListener);
}

(2)定义onClickListener 事件并实现onClick()

View.OnClickListener onClickListener = new View.OnClickListener()
{
    @Override
    public void onClick(View v) 
    {
        //先将四个ImageButton置为默认色
        resetImgs();
        //然后根据点击的Tab切换不同的碎片,并设置对应的ImageButton为pressed时的图片
        switch (v.getId())
        {
            case R.id.id_tab_home:
                selectTab(0);
                break;
            case R.id.id_tab_video:
                selectTab(1);
                break;
            case R.id.id_tab_social:
                selectTab(2);
                break;
            case R.id.id_tab_mine:
                selectTab(3);
                break;
            case R.id.id_tab_settings:
                selectTab(4);
                break;
        }
    }
};

(3)将四个ImageButton设置为默认色

private void resetImgs() 
{
    mImgHome.setImageResource(R.mipmap.tab_home_normal);
    mImgVideo.setImageResource(R.mipmap.tab_video_normal);
    mImgSocial.setImageResource(R.mipmap.tab_social_normal);
    mImgMine.setImageResource(R.mipmap.tab_mine_normal);
    mImgSettings.setImageResource(R.mipmap.settings_norm);
}

(4)实现selectTab()方法,对选中的Tab着重显示,并调用方法设置当前应显示的碎片

 /*选中第i个碎片*/
    private void selectTab(int i) 
    {
        //设置当前点击的Tab所对应的碎片
        setCurrentFragment(i);
        //根据点击的Tab设置对应的ImageButton为pressed时的图片
        switch (i) 
        {
            case 0:
                mImgHome.setImageResource(R.mipmap.tab_home_pressed);
                break;
            case 1:
                mImgVideo.setImageResource(R.mipmap.tab_video_pressed);
                break;
            case 2:
                mImgSocial.setImageResource(R.mipmap.tab_social_pressed);
                break;
            case 3:
                mImgMine.setImageResource(R.mipmap.tab_mine_pressed);
                break;
            case 4:
                mImgSettings.setImageResource(R.mipmap.settings_press);
                break;
        }
    }

(5)显示当前点击的Tab所对应的碎片

private void setCurrentFragment(int i)
{
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction trans = fm.beginTransaction();
    trans.replace(R.id.frag_layout,mFragments.get(i));
    trans.commit();
}

6、实现initFirstRun ()方法, 程序初次运行时显示第一个碎片,调用initFirstRun(0)

  /* 在FrameLayout中显示第i个碎片*/
    private void initFirstRun(int i)
    {
        resetImgs();//重置所有Tab
        selectTab(i);//显示第i个碎片
    }
    
  

7、完整的MainActivity代码

package com.example.myapplication6;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity
{
    //装载Fragment的集合
    private List<Fragment> mFragments;

    //5个Tab对应的布局
    private LinearLayout mTabHome;
    private LinearLayout mTabVideo;
    private LinearLayout mTabSocial;
    private LinearLayout mTabMine;
    private  LinearLayout mTabSettings;

    //5个Tab对应的ImageButton
    private ImageButton mImgHome;
    private ImageButton mImgVideo;
    private ImageButton mImgSocial;
    private ImageButton mImgMine;
    private ImageButton mImgSettings;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();    //初始化控件
        initEvents();     //初始化事件
        initFragments();  //初始化数据
        //第一次运行初始化界面,显示第一个碎片
        //initFirstRun(0);

    }

    /*初始化控件*/
    private void initViews()
    {
        FrameLayout frag_layout = (FrameLayout) findViewById(R.id.frag_layout);

        mTabHome = (LinearLayout) findViewById(R.id.id_tab_home);
        mTabVideo = (LinearLayout) findViewById(R.id.id_tab_video);
        mTabSocial = (LinearLayout) findViewById(R.id.id_tab_social);
        mTabMine = (LinearLayout) findViewById(R.id.id_tab_mine);
        mTabSettings = (LinearLayout) findViewById(R.id.id_tab_settings);

        mImgHome = (ImageButton) findViewById(R.id.id_tab_home_img);
        mImgVideo = (ImageButton) findViewById(R.id.id_tab_video_img);
        mImgSocial = (ImageButton) findViewById(R.id.id_tab_social_img);
        mImgMine = (ImageButton) findViewById(R.id.id_tab_mine_img);
        mImgSettings = (ImageButton) findViewById(R.id.id_tab_settings_img);
    }

    /*设置四个底部导航键的的点击事件*/
    private void initEvents()
    {
        mTabHome.setOnClickListener(onClickListener);
        mTabVideo.setOnClickListener(onClickListener);
        mTabSocial.setOnClickListener(onClickListener);
        mTabMine.setOnClickListener(onClickListener);
        mTabSettings.setOnClickListener(onClickListener);
    }

    View.OnClickListener onClickListener = new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            //先将四个ImageButton置为默认色
            resetImgs();
            //然后根据点击的Tab切换不同的碎片,并设置对应的ImageButton为pressed时的图片
            switch (v.getId())
            {
                case R.id.id_tab_home:
                    selectTab(0);
                    break;
                case R.id.id_tab_video:
                    selectTab(1);
                    break;
                case R.id.id_tab_social:
                    selectTab(2);
                    break;
                case R.id.id_tab_mine:
                    selectTab(3);
                    break;
                case R.id.id_tab_settings:
                    selectTab(4);
                    break;
            }
        }
    };

    /*将四个ImageButton设置为默认色*/
    private void resetImgs()
    {
        mImgHome.setImageResource(R.mipmap.tab_home_normal);
        mImgVideo.setImageResource(R.mipmap.tab_video_normal);
        mImgSocial.setImageResource(R.mipmap.tab_social_normal);
        mImgMine.setImageResource(R.mipmap.tab_mine_normal);
        mImgSettings.setImageResource(R.mipmap.settings_norm);
    }

    /*选中第i个碎片*/
    private void selectTab(int i)
    {
        //设置当前点击的Tab所对应的碎片
        setCurrentFragment(i);
        //根据点击的Tab设置对应的ImageButton为pressed时的图片
        switch (i)
        {
            case 0:
                mImgHome.setImageResource(R.mipmap.tab_home_pressed);
                break;
            case 1:
                mImgVideo.setImageResource(R.mipmap.tab_video_pressed);
                break;
            case 2:
                mImgSocial.setImageResource(R.mipmap.tab_social_pressed);
                break;
            case 3:
                mImgMine.setImageResource(R.mipmap.tab_mine_pressed);
                break;
            case 4:
                mImgSettings.setImageResource(R.mipmap.settings_press);
                break;
        }
    }

    /*显示当前点击的Tab所对应的碎片*/
    private void setCurrentFragment(int i)
    {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction trans = fm.beginTransaction();
        trans.replace(R.id.frag_layout,mFragments.get(i));
        trans.commit();
    }

    //初始化碎片集,每个底部导航按钮对应一个碎片
    private void initFragments()
    {
        mFragments = new ArrayList<>();
        //将5个Fragment加入集合中
        mFragments.add(new Home());
        mFragments.add(new Video());
        mFragments.add(new Social());
        mFragments.add(new Mine());
        mFragments.add(new Settings());
    }

    /* 在FrameLayout中显示第i个碎片*/
    private void initFirstRun(int i)
    {
        resetImgs();//重置所有Tab
        selectTab(i);//显示第i个碎片
    }
}

五、修改activity_main.xml和APP名字

1、activity_main.xml代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/pink3"
    tools:context=".MainActivity">
<!--根据底部Tab动态加载某个碎片的容器-->
    <FrameLayout
        android:id="@+id/frag_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </FrameLayout>
<!-- 底部导航布局-->
    <include layout="@layout/bottom"/>

</LinearLayout>

2、应用名称

<resources>
    <string name="app_name">小粉书</string>
</resources>

六、相关问题

1、单击某个底部导航选项后,项目执行了哪些代码?即如何更新页面(碎片)及底部导航显示?

​ (以Home为例)

/*显示当前点击的Tab所对应的碎片*/
private void setCurrentFragment(int i)
{
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction trans = fm.beginTransaction();
    trans.replace(R.id.frag_layout,mFragments.get(i));
    trans.commit();
}
/* 在FrameLayout中显示第i个碎片*/
private void initFirstRun(int i)
{
    resetImgs();//重置所有Tab
    selectTab(i);//显示第i个碎片
}
/*设置四个底部导航键的的点击事件*/
private void initEvents()
{
    mTabHome.setOnClickListener(onClickListener);
}
public class Home extends Fragment {


    public Home() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_home, container, false);
    }

}

标签:findViewById,ImageButton,安卓,private,public,底部,tab,导航,id
来源: https://www.cnblogs.com/kk2157yy/p/15510034.html