【问题标题】:How to add indicator on a taller-than-default BottomNavigationView?如何在高于默认的 BottomNavigationView 上添加指示器?
【发布时间】:2019-06-24 13:40:45
【问题描述】:

背景

我正在尝试让 BottomNavigationView 更大一些(高度更大一些),同时还让每个项目图标都有一个顶部指示符,表明它已被选中。

类似的东西,但高度更大:

在屏幕截图上有点难以看到,但指示器显示在 BottomNavigationView 项目的最顶部,就在 BottomNavigationView 的阴影下方。

问题

当我设置一个较大的高度时,我得到每个项目仍然采用较小的高度,所以指示器不看顶部:

不仅如此,因为我使用itemBackground设置每个项目的背景有指示器,它现在没有用于点击效果的背景。

我发现了什么

关于高度,我发现this question on StackOverflow,改变高度。唯一的解决方案是覆盖库的尺寸。在这种情况下,只有这样:

<dimen name="design_bottom_navigation_height" tools:override="true">...</dimen>

不过,这只解决了将指标放在顶部的问题。

另外,它看起来像一个肮脏的解决方案,强制为库设置尺寸,正如我所写,因为我使用了 itemBackground ,它不再具有正常的点击效果。

这里是相关代码,只是从 Android Studio 的向导中修改了一点,用于制作“底部导航活动”。其余的和那里一样:

activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/container" 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=".MainActivity">

    <TextView
        android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin" android:text="@string/title_home"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view" android:layout_width="0dp"
        android:layout_height="@dimen/tabs_height" android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp" android:background="?android:attr/windowBackground" app:itemBackground="@drawable/activity_main__tab_background"
        app:labelVisibilityMode="unlabeled" app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu"/>

</androidx.constraintlayout.widget.ConstraintLayout>

dimens.xml

<dimen name="tabs_height">64dp</dimen>
<dimen name="design_bottom_navigation_height" tools:override="true">@dimen/tabs_height</dimen>

activity_main__tab_background.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <layer-list>
            <item android:gravity="top">
                <shape android:shape="rectangle">
                    <size android:height="2dp"/>
                    <solid android:color="#07a5ea"/>
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

问题

如何让指示器位于顶部,同时拥有更大的 BottomNavigationView 且不丢失点击效果?

【问题讨论】:

  • 尝试了同样的事情...按预期运行,点击事件、顶部指示器和自定义高度。我对问题有什么误解吗?
  • 你看到点击效果了吗?而且你没有看到额外的空间?怎么会?在此处查看附加项目:ufile.io/vuyygja9。请试一试。设置比我设置的更大的高度。也尝试点击这些项目。
  • 我刚刚从 dimens 文件中删除了评论...对于这一行 @dimen/tabs_height 并且它正在工作.. .
  • @NaitikSoni 我不明白。什么在起作用?
  • 顶部的指示器,带有点击事件和自定义高度。一切都很好。

标签: android bottomnavigationview


【解决方案1】:

最好的解决方案是在运行时从 kotlin 代码中更改项目 imageView 的边距 这是代码

private fun navigationImagesMargin(view: View) {
        if (view is ViewGroup) {
            for (i in 0 until view.childCount) {
                val child = view.getChildAt(i)
                navigationImagesMargin(child)
            }
        } else if (view is ImageView) {
            val param = view.layoutParams as ViewGroup.MarginLayoutParams
            param.topMargin = convertDpToPx(14)
            view.layoutParams = param
        } 
    }
fun convertDpToPx(dp: Int): Int {
    return Math.round(dp * (resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT))
}

在底部导航视图上的 onCreate 函数调用 navigationImagesMargin 函数

navigationImagesMargin(binding.spBottomNavigation)

但此解决方案需要在每次重新验证视图时调用 navigationImagesMargin 函数,即在 onItemClick 侦听器中,这里是代码

 binding.spBottomNavigation.setOnNavigationItemSelectedListener { it->
            binding.spBottomNavigation.post {
                navigationImagesMargin(binding.spBottomNavigation)
            }
            true
        }

这样,图像将保持在您首次启动时的目标位置

这是包含完整代码的微型仓库的链接 https://github.com/abdulmalekDery/BottomNavigationControl

【讨论】:

  • 对不起,我忘记了。如果你有一个很小的 ​​Github 示例要给我看,我可以对其进行测试并将其标记为已回答。
  • 抱歉耽搁了我已经编辑了答案以包含一个小型 git repo github.com/abdulmalekDery/BottomNavigationControl 的链接
  • 似乎可以工作,但它有一个问题是它添加了片段以便它们合并(文本顶部的文本),并且存储库没有在这里放置链接。你在这里写的代码是唯一需要的吗?
  • 请。为什么它有这个问题?您是否在片段之上添加了片段,并让它们透明,还是什么?
  • 嗨@android开发者我已经添加了导航组件支持,你可以检查一下......如果是这样,请不要忘记将我的答案标记为已接受的答案..随时欢迎我的朋友!
猜你喜欢
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-04
相关资源
最近更新 更多