- 浏览: 2198078 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
Android Support Library 25.0.0 版本中,新增加了一个API –> BottomNavigationView – 底部导航视图。
先来看看这个控件的实现效果。
基本使用
使用起来也很简单
首先在xml中引入该控件
该控件的基本属性有:
app:itemIconTint : 设置菜单图标着色
app:itemTextColor : 设置菜单文本颜色
app:menu : 设置菜单
app:itemBackground : 设置导航栏的背景色
@menu/menu_buttom_navi
与定义普通menu布局一样。
接下来是Java代码
对BottomNavigationView设置选择监听器就可以做一些item切换事件了。
注意事项
源码分析
BottomNavigationView 有几个先关的重要类
它的设计有点类似于开发中的 MVP模式。
先来看 BottomNavigationView 的构造函数
ThemeUtils.checkAppCompatTheme(context) 是用来检测当前主题的。代码很简单,就是判断是否有 colorPrimary 属性。
构造函数中接下来调用了 inflateMenu()
可以看出都是调用的BottomNavigationPresenter的函数。
setUpdateSuspended(true) – 暂停修改menu
setUpdateSuspended(false) — 可以修改menu
在initForMenu()一前一后,设置一个标志来表示当前正在操作menu。
重点来看 BottomNavigationPresenter.initForMenu()
函数内部又是调用的 BottomNavigationMenuView.initialize()
代码中就是一些简单的初始化操作。
接下来看 BottomNavigationPresenter.updateMenuView(true)
第一次创建Menu时,调用的是buildMenuView方法。
BottomNavigationMenuView.buildMenuView()
在 BottomNavigationMenuView类中定义了一个Pool对象,用来缓存BottomNavigationItemView对象。
通过for循环创建了nMenu.size() 个BottomNavigationItemView 对象。
getNewItem()
getNewItem() 类似于 Message.obtain() 的机制。
接着看buildMenuView() ,方法最后面,调用了 BottomNavigationItemView.initialize() ,然后调用 addView(child) 来添加子item视图。
看一下 BottomNavigationItemView的构造函数
代码中映射了一个布局文件
design_bottom_navigation_item.xml
该布局文件由系统提供,包括一个ImageView和两个TextView。
在BottomNavigationMenuView的构造函数中对mAnimationHelper进行了实例化
当版本小于14(Android 4.0)时,是没有动画效果的。
Android 4.0及之上的版本
代码中定义了文本缩放动画 – TextScale
然后来看 BottomNavigationItemView的点击事件。
在初始化这些子itemView的时候就设置了onClickListener
activateNewButtom()
先产生动画,然后切换被选中和之前选中的item的状态。
mShiftingMode 表示是否偏移值。当菜单个数大于3时,为true。
先来看看这个控件的实现效果。
基本使用
使用起来也很简单
首先在xml中引入该控件
<android.support.design.widget.BottomNavigationView android:id="@+id/bottom_navi_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" app:itemBackground="@android:color/white" app:menu="@menu/menu_bottom_navi" />
该控件的基本属性有:
引用
app:itemIconTint : 设置菜单图标着色
app:itemTextColor : 设置菜单文本颜色
app:menu : 设置菜单
app:itemBackground : 设置导航栏的背景色
@menu/menu_buttom_navi
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_recent" android:icon="@drawable/ic_history_black_24dp" android:title="@string/menu_recents" /> <item android:id="@+id/menu_favorites" android:icon="@drawable/ic_favorite_black_24dp" android:title="@string/menu_favorites" /> <item android:id="@+id/menu_nearby" android:icon="@drawable/ic_place_black_24dp" android:title="@string/menu_nearby" /> <item android:id="@+id/menu_navi" android:icon="@drawable/ic_navigation_black_24dp" android:title="@string/menu_navigation" /> </menu>
与定义普通menu布局一样。
接下来是Java代码
bottomNaviView = (BottomNavigationView) findViewById(R.id.bottom_navi_view); bottomNaviView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.menu_recent: break; case R.id.menu_favorites: break; case R.id.menu_nearby: break; case R.id.menu_navi: break; } return true; } });
对BottomNavigationView设置选择监听器就可以做一些item切换事件了。
注意事项
- 底部导航栏默认高度是56dp
- 菜单只能是3-5个
源码分析
BottomNavigationView 有几个先关的重要类
- BottomNavigationView
- BottomNavigationMenu
- BottomNavigationMenuView
- BottomNavigationPresenter
它的设计有点类似于开发中的 MVP模式。
先来看 BottomNavigationView 的构造函数
public BottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); ThemeUtils.checkAppCompatTheme(context); //检测当前主题 // Create the menu mMenu = new BottomNavigationMenu(context); mMenuView = new BottomNavigationMenuView(context); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER; mMenuView.setLayoutParams(params); mPresenter.setBottomNavigationMenuView(mMenuView); mMenuView.setPresenter(mPresenter); mMenu.addMenuPresenter(mPresenter); // Custom attributes // ...省略若干代码 if (a.hasValue(R.styleable.BottomNavigationView_menu)) { inflateMenu(a.getResourceId(R.styleable.BottomNavigationView_menu, 0)); // 加载menu } a.recycle(); addView(mMenuView, params); // mMenu.setCallback(new MenuBuilder.Callback() { // 设置监听器 @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { return mListener != null && mListener.onNavigationItemSelected(item); } @Override public void onMenuModeChange(MenuBuilder menu) {} }); }
ThemeUtils.checkAppCompatTheme(context) 是用来检测当前主题的。代码很简单,就是判断是否有 colorPrimary 属性。
class ThemeUtils { private static final int[] APPCOMPAT_CHECK_ATTRS = { android.support.v7.appcompat.R.attr.colorPrimary }; static void checkAppCompatTheme(Context context) { TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS); final boolean failed = !a.hasValue(0); if (a != null) { a.recycle(); } if (failed) { throw new IllegalArgumentException("You need to use a Theme.AppCompat theme " + "(or descendant) with the design library."); } } }
构造函数中接下来调用了 inflateMenu()
public void inflateMenu(int resId) { mPresenter.setUpdateSuspended(true); getMenuInflater().inflate(resId, mMenu); mPresenter.initForMenu(getContext(), mMenu); mPresenter.setUpdateSuspended(false); mPresenter.updateMenuView(true); }
可以看出都是调用的BottomNavigationPresenter的函数。
setUpdateSuspended(true) – 暂停修改menu
setUpdateSuspended(false) — 可以修改menu
在initForMenu()一前一后,设置一个标志来表示当前正在操作menu。
重点来看 BottomNavigationPresenter.initForMenu()
@Override public void initForMenu(Context context, MenuBuilder menu) { mMenuView.initialize(mMenu); mMenu = menu; }
函数内部又是调用的 BottomNavigationMenuView.initialize()
@Override public void initialize(MenuBuilder menu) { mMenu = menu; if (mMenu == null) return; if (mMenu.size() > mActiveButton) { mMenu.getItem(mActiveButton).setChecked(true); } }
代码中就是一些简单的初始化操作。
接下来看 BottomNavigationPresenter.updateMenuView(true)
@Override public void updateMenuView(boolean cleared) { if (mUpdateSuspended) return; if (cleared) { mMenuView.buildMenuView(); } else { mMenuView.updateMenuView(); } }
第一次创建Menu时,调用的是buildMenuView方法。
BottomNavigationMenuView.buildMenuView()
public void buildMenuView() { if (mButtons != null) { for (BottomNavigationItemView item : mButtons) { sItemPool.release(item); } } removeAllViews(); mButtons = new BottomNavigationItemView[mMenu.size()]; // 当menu item大于3个的时候,会出现缩放动画 mShiftingMode = mMenu.size() > 3; for (int i = 0; i < mMenu.size(); i++) { mPresenter.setUpdateSuspended(true); mMenu.getItem(i).setCheckable(true); mPresenter.setUpdateSuspended(false); BottomNavigationItemView child = getNewItem(); mButtons[i] = child; child.setIconTintList(mItemIconTint); child.setTextColor(mItemTextColor); child.setItemBackground(mItemBackgroundRes); child.setShiftingMode(mShiftingMode); // 单个item -- BottomNavigationItenView 的初始化操作 child.initialize((MenuItemImpl) mMenu.getItem(i), 0); child.setItemPosition(i); // 设置点击事件 child.setOnClickListener(mOnClickListener); // 添加子视图 addView(child); } }
在 BottomNavigationMenuView类中定义了一个Pool对象,用来缓存BottomNavigationItemView对象。
private static final Pools.Pool<BottomNavigationItemView> sItemPool = new Pools.SynchronizedPool<>(5);
通过for循环创建了nMenu.size() 个BottomNavigationItemView 对象。
BottomNavigationItemView child = getNewItem(); mButtons[i] = child;
getNewItem()
private BottomNavigationItemView getNewItem() { BottomNavigationItemView item = sItemPool.acquire(); if (item == null) { item = new BottomNavigationItemView(getContext()); } return item; }
getNewItem() 类似于 Message.obtain() 的机制。
接着看buildMenuView() ,方法最后面,调用了 BottomNavigationItemView.initialize() ,然后调用 addView(child) 来添加子item视图。
@Override public void initialize(MenuItemImpl itemData, int menuType) { mItemData = itemData; setCheckable(itemData.isCheckable()); setChecked(itemData.isChecked()); setEnabled(itemData.isEnabled()); setIcon(itemData.getIcon()); setTitle(itemData.getTitle()); setId(itemData.getItemId()); }
看一下 BottomNavigationItemView的构造函数
public BottomNavigationItemView(@NonNull Context context) { this(context, null); } public BottomNavigationItemView(@NonNull Context context, AttributeSet attrs) { this(context, attrs, 0); } public BottomNavigationItemView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final Resources res = getResources(); int inactiveLabelSize = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_text_size); int activeLabelSize = res.getDimensionPixelSize( R.dimen.design_bottom_navigation_active_text_size); mDefaultMargin = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_margin); mShiftAmount = inactiveLabelSize - activeLabelSize; mScaleUpFactor = 1f * activeLabelSize / inactiveLabelSize; mScaleDownFactor = 1f * inactiveLabelSize / activeLabelSize; // 注意下面的代码 LayoutInflater.from(context).inflate(R.layout.design_bottom_navigation_item, this, true); setBackgroundResource(R.drawable.design_bottom_navigation_item_background); mIcon = (ImageView) findViewById(R.id.icon); mSmallLabel = (TextView) findViewById(R.id.smallLabel); mLargeLabel = (TextView) findViewById(R.id.largeLabel); }
代码中映射了一个布局文件
design_bottom_navigation_item.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/icon" android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/design_bottom_navigation_margin" android:layout_marginBottom="@dimen/design_bottom_navigation_margin" android:duplicateParentState="true" /> <android.support.design.internal.BaselineLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/design_bottom_navigation_margin" android:layout_gravity="bottom|center_horizontal" android:duplicateParentState="true"> <TextView android:id="@+id/smallLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/design_bottom_navigation_text_size" android:duplicateParentState="true" /> <TextView android:id="@+id/largeLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" android:textSize="@dimen/design_bottom_navigation_active_text_size" android:duplicateParentState="true" /> </android.support.design.internal.BaselineLayout> </merge>
该布局文件由系统提供,包括一个ImageView和两个TextView。
引用
当菜单项大于3个,切换item时,被选中的item会将largeLabel显示,将smallLabel隐藏。然后改变ImageView和TextView的margin值达到动画效果。
在BottomNavigationMenuView的构造函数中对mAnimationHelper进行了实例化
private final BottomNavigationAnimationHelperBase mAnimationHelper;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { mAnimationHelper = new BottomNavigationAnimationHelperIcs(); } else { mAnimationHelper = new BottomNavigationAnimationHelperBase(); }
当版本小于14(Android 4.0)时,是没有动画效果的。
class BottomNavigationAnimationHelperBase { void beginDelayedTransition(ViewGroup view) { // Do nothing. } }
Android 4.0及之上的版本
class BottomNavigationAnimationHelperIcs extends BottomNavigationAnimationHelperBase { private static final long ACTIVE_ANIMATION_DURATION_MS = 115L; private final TransitionSet mSet; BottomNavigationAnimationHelperIcs() { mSet = new AutoTransition(); mSet.setOrdering(TransitionSet.ORDERING_TOGETHER); mSet.setDuration(ACTIVE_ANIMATION_DURATION_MS); mSet.setInterpolator(new FastOutSlowInInterpolator()); TextScale textScale = new TextScale(); mSet.addTransition(textScale); } void beginDelayedTransition(ViewGroup view) { TransitionManager.beginDelayedTransition(view, mSet); } }
代码中定义了文本缩放动画 – TextScale
然后来看 BottomNavigationItemView的点击事件。
在初始化这些子itemView的时候就设置了onClickListener
child.initialize((MenuItemImpl) mMenu.getItem(i), 0); child.setItemPosition(i); // 设置点击事件 child.setOnClickListener(mOnClickListener);
mOnClickListener = new OnClickListener() { @Override public void onClick(View v) { final BottomNavigationItemView itemView = (BottomNavigationItemView) v; final int itemPosition = itemView.getItemPosition(); activateNewButton(itemPosition); mMenu.performItemAction(itemView.getItemData(), mPresenter, 0); } };
activateNewButtom()
private void activateNewButton(int newButton) { if (mActiveButton == newButton) return; mAnimationHelper.beginDelayedTransition(this); // 产生动画 mPresenter.setUpdateSuspended(true); mButtons[mActiveButton].setChecked(false); // 旧的被激活的按钮切换成未被激活状态 mButtons[newButton].setChecked(true); // 将新点击的按钮切换到被激活状态 mPresenter.setUpdateSuspended(false); mActiveButton = newButton; // 记录当前被激活按钮的位置 }
先产生动画,然后切换被选中和之前选中的item的状态。
@Override public void setChecked(boolean checked) { mItemData.setChecked(checked); ViewCompat.setPivotX(mLargeLabel, mLargeLabel.getWidth() / 2); ViewCompat.setPivotY(mLargeLabel, mLargeLabel.getBaseline()); ViewCompat.setPivotX(mSmallLabel, mSmallLabel.getWidth() / 2); ViewCompat.setPivotY(mSmallLabel, mSmallLabel.getBaseline()); if (mShiftingMode) { if (checked) { LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams(); iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; iconParams.topMargin = mDefaultMargin; mIcon.setLayoutParams(iconParams); mLargeLabel.setVisibility(VISIBLE); ViewCompat.setScaleX(mLargeLabel, 1f); ViewCompat.setScaleY(mLargeLabel, 1f); } else { LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams(); iconParams.gravity = Gravity.CENTER; iconParams.topMargin = mDefaultMargin; mIcon.setLayoutParams(iconParams); mLargeLabel.setVisibility(INVISIBLE); ViewCompat.setScaleX(mLargeLabel, 0.5f); ViewCompat.setScaleY(mLargeLabel, 0.5f); } mSmallLabel.setVisibility(INVISIBLE); } else { if (checked) { LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams(); iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; iconParams.topMargin = mDefaultMargin + mShiftAmount; mIcon.setLayoutParams(iconParams); mLargeLabel.setVisibility(VISIBLE); mSmallLabel.setVisibility(INVISIBLE); ViewCompat.setScaleX(mLargeLabel, 1f); ViewCompat.setScaleY(mLargeLabel, 1f); ViewCompat.setScaleX(mSmallLabel, mScaleUpFactor); ViewCompat.setScaleY(mSmallLabel, mScaleUpFactor); } else { LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams(); iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; iconParams.topMargin = mDefaultMargin; mIcon.setLayoutParams(iconParams); mLargeLabel.setVisibility(INVISIBLE); mSmallLabel.setVisibility(VISIBLE); ViewCompat.setScaleX(mLargeLabel, mScaleDownFactor); ViewCompat.setScaleY(mLargeLabel, mScaleDownFactor); ViewCompat.setScaleX(mSmallLabel, 1f); ViewCompat.setScaleY(mSmallLabel, 1f); } } refreshDrawableState(); }
mShiftingMode 表示是否偏移值。当菜单个数大于3时,为true。
发表评论
-
带你深入理解 FLUTTER 中的字体“冷”知识
2020-08-10 23:40 627本篇将带你深入理解 Flutter 开发过程中关于字体和文 ... -
Flutter -自定义日历组件
2020-03-01 17:56 1104颜色文件和屏幕适配的文件 可以自己给定 import ... -
Dart高级(一)——泛型与Json To Bean
2020-02-23 19:13 996从 Flutter 发布到现在, 越来越多人开始尝试使用 Da ... -
flutter loading、Progress进度条
2020-02-21 17:03 1172Flutter Progress 1 条形无固定值进度条 ... -
Flutter使用Https加载图片
2020-02-21 01:39 1006Flutter使用Https加载图片 使用http加载图片出 ... -
flutter shared_preferences 异步变同步
2020-02-21 00:55 840前言 引用 在开发原生iOS或Native应用时,一般有判断上 ... -
Flutter TextField边框颜色
2020-02-19 21:31 930监听要销毁 myController.dispose(); T ... -
flutter Future的正确用法
2020-02-18 21:55 801在flutter中经常会用到异步任务,dart中异步任务异步处 ... -
记一次Flutter简单粗暴处理HTTPS证书检验方法
2020-02-18 14:13 955最近在做Flutter项目到了遇到一个无解的事情,当使用Ima ... -
flutter 获取屏幕宽度高度 通知栏高度等屏幕信息
2019-07-27 08:39 1330##MediaQuery MediaQuery.of(con ... -
关于flutter RefreshIndicator扩展listview下拉刷新的问题
2019-07-10 19:40 1120当条目过少时listview某些嵌套情况下可能不会滚动(条目 ... -
flutter listview 改变状态的时候一直无限添加
2019-07-10 16:01 781setstate的时候会一直无限的调用listview.bui ... -
Flutter Android端启动白屏问题的解决
2019-07-09 00:51 1507问题描述 Flutter 应用在 Android 端上启动时 ... -
Flutter中SnackBar使用
2019-07-08 23:43 770底部弹出,然后在指定时间后消失。 注意: build(Bui ... -
Flutter 之点击空白区域收起键盘
2019-07-08 18:43 1782点击空白处取消TextField焦点这个需求是非常简单的,在学 ... -
Flutter 弹窗 Dialog ,AlertDialog,IOS风格
2019-07-08 18:04 1373import 'package:flutter/mate ... -
flutter ---TextField 之 输入类型、长度限制
2019-07-08 14:30 2320TextField想要实现输入类型、长度限制需要先引入impo ... -
【flutter 溢出BUG】键盘上显示bottom overflowed by 104 PIXELS
2019-07-08 11:13 1554一开始直接使用Scaffold布局,body:new Colu ... -
解决Flutter项目卡在Initializing gradle...界面的问题
2019-07-07 12:53 867Flutter最近很火,我抽出了一点时间对Flutter进行了 ... -
关于android O 上 NotificationChannel 的一些注意事项
2019-07-04 11:47 934最近在适配android O,遇到个问题,应用中原本有设置界面 ...
相关推荐
在Android开发中,BottomNavigationView(底部导航视图)是一个常用组件,用于在多个视图间进行切换。在设计用户界面时,我们有时需要对它的默认行为进行自定义,比如在这个场景下,我们要去除 BottomNavigationView...
`Fragment`、`ViewPager`和`BottomNavigationView`是Android SDK提供的重要组件,它们可以帮助开发者轻松实现这样的设计。本教程将详细解释如何利用这些组件来构建一个可以进行页面切换的App。 首先,`Fragment`是...
在Android应用开发中,BottomNavigationView是一个常用的组件,用于在底部展示多个页面间的切换导航,而ViewPager则用于实现页面滑动浏览。当这两个组件结合使用时,可能会遇到一个问题:BottomNavigationView的图标...
在Android应用开发中,`BottomNavigationView` 是一个非常重要的组件,它用于实现底部导航功能,让用户可以在多个主要视图之间轻松切换。这个组件通常包含3到5个图标和相应的文字标签,代表应用的主要功能模块。在...
在Android应用开发中,底部导航栏(BottomNavigationView)是一个常用组件,它允许用户在多个顶层导航之间进行切换,通常位于屏幕底部。这个控件在Android Design Support Library中提供,可以帮助开发者实现符合...
在Android应用开发中,BottomNavigationView是一个非常常用的组件,它用于在底部展示多个可选的页面,使得用户可以方便地在各个功能之间切换。Kotlin作为Google推荐的Android开发语言,其简洁的语法使得与Bottom...
BottomNavigationView是Android支持库中的一个组件,用于在底部显示一组可切换的标签,通常用于在应用的主要功能之间进行导航。这个组件遵循Material Design指南,提供了美观且易于使用的选项卡效果。 要在Android...
【BottomNavigationView底部导航demo】是Android开发中的一个关键知识点,用于在应用的底部提供一种便捷的多页面切换方式。在Android应用设计中,底部导航栏(Bottom Navigation)是一种常见的界面元素,它允许用户...
Android 使用BottomNavigationView实现底部导航栏,在Android Support Library 25 中增加了 BottomNavigationView 控件,官方为我们提供了这样这一个控件。
"带红点的BottomNavigationView+viewpager demo" 这个标题表明我们将会探讨一个Android应用开发中的示例项目,该项目结合了`BottomNavigationView`和`ViewPager`,并且在底部导航栏的某个选项上显示了一个红色的...
在Android开发中,`BottomNavigationView` 和 `ViewPager` 是两种常用的组件,用于构建具有多个页面切换功能的用户界面。`BottomNavigationView` 提供了一个底部导航栏,通常包含多个图标和对应的标签,允许用户在...
在Android应用开发中,BottomNavigationView和ViewPager是两个常用的组件,它们可以协同工作,为用户提供一个交互式的底部导航体验。本文将深入探讨如何使用这两个组件来实现一个类似小程序的底部导航栏功能。 首先...
在Android应用开发中,BottomNavigationView是一种常用的组件,用于在底部展示多个可切换的视图,类似于底部导航栏。本教程将详细介绍如何在Android Studio中利用BottomNavigationView实现底部tabs功能。 首先,...
在Android应用开发中,`ViewPager`和`BottomNavigationView`是两个非常重要的组件,它们用于创建交互丰富的用户界面。`ViewPager`通常用来实现页面滑动效果,而`BottomNavigationView`则常用于底部导航栏,提供多...
在Android应用开发中,创建一个带有底部导航栏(BottomNavigationView)的应用是非常常见的需求。这个功能允许用户在多个页面间轻松切换,通常与ViewPager结合使用,用于管理不同的Fragment。本篇文章将详细讲解如何...
在Android应用开发中,`BottomNavigationView`是一种常用的组件,用于创建底部导航栏,它允许用户在不同的内容区域之间切换,通常结合`ViewPager`和`Fragment`来实现更流畅的交互体验。下面我们将深入探讨`Bottom...
通过自定义BottomNavigationView +menu 快速实现底部栏切换 ,并可以结合ViewPager +Fragment ,代码量少,实现方便
在Android应用开发中,BottomNavigationView是一种常见的用户界面组件,它位于屏幕底部,通常包含3到5个图标,用于在不同的页面或功能之间切换。这个组件是Google Material Design规范的一部分,可以提供良好的用户...
在Android应用开发中,`BottomNavigationView`和`ViewPager`是两个非常重要的组件,它们常常被结合起来使用,以实现用户友好的界面导航。`BottomNavigationView`是Google提供的Material Design组件,用于在屏幕底部...
本文将深入探讨如何使用`BottomNavigationView`和`CoordinatorLayout`组件来实现顶部导航栏和底部导航栏随着用户的滑动动作而进行隐藏与显示的效果。这两个组件是Android支持库中的关键组件,能够帮助开发者构建现代...