Android---简易的底部导航栏
目录
一、activity_main.xml布局
二、给ViewPager2 创建适配器
三、ViewPager2 数据源
四、MainActivity.java类
1、初始化数据源。
2、ViewPager2 页面改变监听
3、BottomNavigationView 的每个 item 点击的监听
这里简单演示实现效果,实现快速开发,并没有太好的UI界面。当掌握好了知识点,再来优化界面。实现上面的效果主要用到 ViewPager2 + Fragment + BottomNavigationView
一、activity_main.xml布局
这里只有两个控件。第一个 ViewPager2,用来放 Fragment。第二个是 BottomNavigationView 实现底部导航。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"xmlns:app="http://schemas.android.com/apk/res-auto"tools:context=".MainActivity"><androidx.viewpager2.widget.ViewPager2android:id="@+id/main_viewPager"android:layout_width="0dp"android:layout_height="0dp"android:layout_marginStart="8dp"android:layout_marginLeft="0dp"android:layout_marginTop="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="0dp"android:layout_marginBottom="19dp"app:layout_constraintBottom_toTopOf="@+id/main_bottomNavigationView"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/main_bottomNavigationView"android:layout_width="0dp"android:layout_height="78dp"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="5dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/main_viewPager"app:menu="@menu/bottomnavigationitem"/></androidx.constraintlayout.widget.ConstraintLayout>
给底部导航增加菜单按钮。在 BottomNavigationView 里添加属性 app:menu="@menu/bottomnavigationitem"。在 res 目录下 New --> Directory 新建一个menu目录。在menu目录上 New --> Menu Source File 新建一个 bottomnavigationitem.xml 文件。
在bottomnavigationitem.xml 里添加一个 item 就是在 底部导航栏里添加了一个可点击的 tab 按钮。注意,item 里面的 icon 属性你可以自己找一下好看的icon,这里简单用 mipmap 里的 ic_launcher.webp 来作为 icon。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/fragment_1"android:icon="@mipmap/ic_launcher"android:title="T1"/><itemandroid:id="@+id/fragment_2"android:icon="@mipmap/ic_launcher"android:title="T2"/><itemandroid:id="@+id/fragment_3"android:icon="@mipmap/ic_launcher"android:title="T3"/><itemandroid:id="@+id/fragment_4"android:icon="@mipmap/ic_launcher"android:title="T4"/><itemandroid:id="@+id/fragment_5"android:icon="@mipmap/ic_launcher"android:title="T5"/></menu>
二、给ViewPager2 创建适配器
ViewPager2 是高级 UI。通过适配器 Adapter 来适配数据源。创建一个 MyFragmentStateAdapter.class 类,继承 FragmentStateAdapter,实现两个方法 createFragment() 和 getItemCount()。
注意:
1、ViewPager 是与 FragmentPagerAdapter 搭配的。而 FragmentPagerAdapter 继承自 PagerAdapter。而 FragmentPagerAdapter 已经被官方给废弃了。
2、ViewPager2 是与 FragmentStateAdapter 搭配的。而 FragmentStateAdapter 继承自 RecyclerView.Adapter。因此可以用到 RecyclerView 的性质,比如垂直滑动效果。
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;import java.util.List;public class MyFragmentStateAdapter extends FragmentStateAdapter {private List<Fragment> mData;public MyFragmentStateAdapter(FragmentActivity fragmentActivity, List<Fragment> mData) {super(fragmentActivity);this.mData = mData;}@NonNull@Overridepublic Fragment createFragment(int position) {return mData.get(position);}@Overridepublic int getItemCount() {return mData == null ? 0 : mData.size();}
}
三、ViewPager2 数据源
创建一个 Fragment 来作为 ViewPager2 的数据源。
public class MyFragment extends Fragment{/*** 的到当前Fragment 的一个实例*/public static MyFragment newInstance(int position){Bundle bundle = new Bundle();bundle.putInt("Position", position);MyFragment fragment = new MyFragment();fragment.setArguments(bundle);return fragment;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d(TAG, tabIndex + "fragment" + "onCreate");}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return super.onCreateView(inflater, container, savedInstanceState);}}
四、MainActivity.java类
1、初始化数据源。
/*** 初始化数据*/private List<Fragment> initData(){mData = new ArrayList<>();for (int i = 0; i < 5; i++) {mData.add(MyFragment.newInstance(i));}return mData;}
2、ViewPager2 页面改变监听
ViewPager2 里对页面改变的监听是 OnPageChangeCallback(); ViewPager 是 OnPageChangeListener(), 但是已经被废弃了。
BottomNavigationView.setSelectedItemId(itemID) 根据itemID 设置选中的 item。当滑动 Fragment 时,BottomNavigationView 的每个 item 也会相应的改变。做到每个Fragment 与 下面BottomNavigationView 的每个 item 绑定。
ViewPager2.OnPageChangeCallback onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);int itemID = R.id.fragment_1;switch (position) {case 0:itemID = R.id.fragment_1;break;case 1:itemID = R.id.fragment_2;break;case 2:itemID = R.id.fragment_3;break;case 3:itemID = R.id.fragment_4;break;case 4:itemID = R.id.fragment_5;break;default:break;}//TODO 当Fragment滑动改变时,底部的Tab也跟着改变mBottomNavigationView.setSelectedItemId(itemID);}};
3、BottomNavigationView 的每个 item 点击的监听
对于底部导航栏 item 的监听应该是 OnNavigationItemSelectedListener,但是该方法已经被 google 官方给废弃了,所以这里用 OnItemSelectedListener 来代替。
ViewPager.setCurrentItem() 方法,设置当前 Viewpager 要加载的item (Fragment),这里做到 ViewPager2 的每一个 Fragment 与 底部导航栏的每个 item 绑定。
NavigationBarView.OnItemSelectedListener onItemSelectedListener = new NavigationBarView.OnItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(@NonNull MenuItem item) {// 点击Tab, 切换对应的 Fragmentswitch (item.getItemId()) {case R.id.fragment_1://TODO 当点击 Tab 时,ViewPager 也切换到对应的 FragmentmViewPager.setCurrentItem(0, true);return true;case R.id.fragment_2:mViewPager.setCurrentItem(1, true);return true;case R.id.fragment_3:mViewPager.setCurrentItem(2, true);return true;case R.id.fragment_4:mViewPager.setCurrentItem(3, true);return true;case R.id.fragment_5:mViewPager.setCurrentItem(4, true);return true;}return false;}};
MainActivity的完整代码
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;import com.example.viewpager2_demo.adapter.MyFragmentStateAdapter;
import com.example.viewpager2_demo.fragment.MyFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;import java.util.ArrayList;
import java.util.List;@RequiresApi(api = Build.VERSION_CODES.M)
public class MainActivity extends AppCompatActivity {private ViewPager2 mViewPager;private BottomNavigationView mBottomNavigationView;private List<Fragment> mData;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mViewPager = findViewById(R.id.main_viewPager);mBottomNavigationView = findViewById(R.id.main_bottomNavigationView);// 设置适配器mViewPager.setAdapter(new MyFragmentStateAdapter(this, initData()));mViewPager.setOffscreenPageLimit(1); //设置页面缓存的个数,默认1个//设置底部导航栏 item 点击的监听mBottomNavigationView.setOnItemSelectedListener(onItemSelectedListener);// 设置 ViewPager2 页面改变的监听mViewPager.registerOnPageChangeCallback(onPageChangeCallback);}ViewPager2.OnPageChangeCallback onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);int itemID = R.id.fragment_1;switch (position) {case 0:itemID = R.id.fragment_1;Log.d("HL", "1");break;case 1:itemID = R.id.fragment_2;Log.d("HL", "2");break;case 2:itemID = R.id.fragment_3;Log.d("HL", "3");break;case 3:itemID = R.id.fragment_4;Log.d("HL", "4");break;case 4:itemID = R.id.fragment_5;Log.d("HL", "5");break;default:break;}//TODO 当Fragment滑动改变时,底部的Tab也跟着改变mBottomNavigationView.setSelectedItemId(itemID);}};NavigationBarView.OnItemSelectedListener onItemSelectedListener = new NavigationBarView.OnItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(@NonNull MenuItem item) {// 点击Tab, 切换对应的 Fragmentswitch (item.getItemId()) {case R.id.fragment_1://TODO 当点击 Tab 时,ViewPager 也切换到对应的 FragmentmViewPager.setCurrentItem(0, true);return true;case R.id.fragment_2:mViewPager.setCurrentItem(1, true);return true;case R.id.fragment_3:mViewPager.setCurrentItem(2, true);return true;case R.id.fragment_4:mViewPager.setCurrentItem(3, true);return true;case R.id.fragment_5:mViewPager.setCurrentItem(4, true);return true;}return false;}};/*** 初始化数据*/private List<Fragment> initData(){mData = new ArrayList<>();for (int i = 0; i < 5; i++) {mData.add(MyFragment.newInstance(i));}return mData;}
}
Android---简易的底部导航栏相关推荐
- android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...
Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...
- php仿微信底部菜单,Android实现简单底部导航栏 Android仿微信滑动切换效果
Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...
- android滑动菜单图标,Android实现简单底部导航栏 Android仿微信滑动切换效果
Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...
- android 底部滑动效果怎么做,Android实现简单底部导航栏 Android仿微信滑动切换效果...
android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义view配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...
- android仿咸鱼底部导航栏,Flutter沉浸式状态栏/AppBar导航栏/仿咸鱼底部凸起导航栏效果...
如下图:状态栏是指android手机顶部显示手机状态信息的位置. android 自4.4开始新加入透明状态栏功能,状态栏可以自定义颜色背景,使titlebar能够和状态栏融为一体,增加沉浸感. 如上 ...
- Android仿Qzone底部导航栏加号弹出菜单
最近看到QQ空间 新浪微博-.好多应用底部导航栏都有加号点击弹出菜单,于是就写了一个demo,来给没做过这个功能的小伙伴一个参考,希望对大家有所帮助,demo中的图片均来源于Qzone 仅作为学习交流 ...
- react native Android 键盘将底部导航栏/按钮顶起
比如,当输入框中输入信息时,键盘会把底部导航栏顶起,就会很丑啊! 解决办法: 1.找到文件 android/app/src/main/AndroidManifest.xml,修改android:win ...
- Android界面被底部导航栏挡住
资料 解决android 显示内容被底部导航栏遮挡的问题 AndroidBug5497Workaround Android手机底部NavigationBar挡住界面的解决方法 android 显示内容 ...
- Android中的底部导航栏切换TabContainerView
前言:在GitHub上看到一个框架,实现底部导航栏切换,感觉不错,就在这里总结一下. 参考:https://www.jianshu.com/p/9aaff43bbf9f https://github. ...
- android——暴力隐藏底部导航栏
最近在做平板项目,boss要求隐藏掉底部导航栏,各种谷歌百度了半天,可愁死我了.因为导航栏是系统自带的,要实现隐藏要么修改framwork层代码,要么想点别的招.本宝菜鸟一只,哪里会啥修改framwo ...
最新文章
- Java之美之设计模式
- 4.通过三个交换机实现VLAN间通信
- Java的Arrays.sort()良心总结
- CPU you selected does not support x86-64 instruction set
- mysql savepoint 什么意思_关于MySQL中savepoint语句使用时所出现的错误
- P2922-[USACO08DEC]秘密消息Secret Message【Trie,字符串】
- iOS有哪些数据类型/基本数据类型?
- 在Mac OS X上安装Oracle客户端
- error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead.
- 机械设计说明书_如何做机械设计课程设计?这篇文章总结很详细
- Windows服务简单实例
- sql出现列名无效的原因_SQL数据库中的数据类型与表结构的创建
- 面向对象编程设计练习题(2)
- 可任意设置时间的ppt倒计时软件
- Android oem 解锁
- 手把手教你修改iOS版QQ的运动步数
- python中星号怎么打出来_Python中的星号符号
- Sql取得两表关联数据
- 6天面试、斩获6家硅谷巨头Offer,我是如何做到的?
- ldo低压差线性稳压器电路解析
热门文章
- 这些联盟可以去注册试一下
- 五面阿里拿下飞猪事业部offer,先睹为快
- 信息化故事--温州的传奇(11)从“进城务工”看“温州新版自闭症”
- QTextStream 类(文本流)和 QDataStream 类(数据流)
- 查询表空间建立表空间和删除表空间
- 好书收藏:读书知多少
- 用户登陆成功修改SessionId
- payjs插件php,基于payjs的discuz支付插件制作
- Echarts折线科技图
- android新闻客户端答辩,头条客户端 Android