基于用户登录 Kotlin 的底部导航菜单

如何解决基于用户登录 Kotlin 的底部导航菜单

是否可以根据登录用户在 Kotlin 中隐藏/显示底部导航菜单项? 我在底部导航中有一些我不想向所有用户显示的项目。

编辑: 这是我的代码

用户不在时,我想从菜单删除 @+id/navigation_products,例如 abc 和 xyz。

bottom_nav_menu.xml

    <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_vector_dashboard"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_products"
        android:icon="@drawable/ic_vector_products"
        android:title="@string/title_products" />

    <item
        android:id="@+id/navigation_orders"
        android:icon="@drawable/ic_vector_orders"
        android:title="@string/title_orders" />

    <item
        android:id="@+id/navigation_sold_products"
        android:icon="@drawable/ic_vector_sold_products"
        android:title="@string/title_sold_products" />

    <item
        android:id="@+id/navigation_orders_by_status"
        android:icon="@drawable/ic_vector_sold_products"
        android:title="@string/title_orders_by_status" />
</menu>

mobile_navigation.xml

    <?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/mobile_navigation"
    app:startDestination="@+id/navigation_dashboard">

    <fragment
        android:id="@+id/navigation_dashboard"
        android:name="com.ui.fragments.DashboardFragment"
        android:label="@string/title_dashboard"
        tools:layout="@layout/fragment_dashboard" />

    <fragment
        android:id="@+id/navigation_products"
        android:name="com.ui.fragments.ProductsFragment"
        android:label="@string/title_products"
        tools:layout="@layout/fragment_products" />

    <fragment
        android:id="@+id/navigation_orders"
        android:name="com.ui.fragments.OrdersFragment"
        android:label="@string/title_orders"
        tools:layout="@layout/fragment_orders" />

    <fragment
        android:id="@+id/navigation_sold_products"
        android:name="com.ui.fragments.soldProductsFragment"
        android:label="@string/title_sold_products"
        tools:layout="@layout/fragment_sold_products" />

    <fragment
        android:id="@+id/navigation_orders_by_status"
        android:name="com.ui.fragments.OrdersByStatusFragment"
        android:label="@string/title_orders_by_status"
        tools:layout="@layout/fragment_sold_products" />
</navigation>

仪表板活动.kt

class DashboardActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dashboard)

        supportActionBar!!.setBackgroundDrawable(
            ContextCompat.getDrawable(
                this@DashboardActivity,R.drawable.app_gradient_color_background
            )
        )

        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
      
        val appBarConfiguration = AppBarConfiguration(
            setof(
                R.id.navigation_products,R.id.navigation_dashboard,R.id.navigation_orders,R.id.navigation_sold_products,R.id.navigation_orders_by_status
            )
        )
        setupActionBarWithNavController(navController,appBarConfiguration)

        navView.setupWithNavController(navController)
    }

    override fun onBackpressed() {
        doubleBackToExit()
    }

}

解决方法

是的,这是可能的。对于这样的逻辑,您必须动态更改底部导航菜单。为方便起见,您可以添加以下依赖项:

// Event Bus
implementation 'org.greenrobot:eventbus:3.2.0'

然后让我们假设以下内容:

活动xml

<layout>

    <androidx.constraintlayout.widget.ConstraintLayout 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=".framework.ui.view.MainActivity">

        <fragment
            android:id="@+id/fragment_container"
            android:name="com.example.app.framework.utils.MainNavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="@dimen/wrapContent"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/nav_main" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:itemHorizontalTranslationEnabled="false"
            app:labelVisibilityMode="labeled"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:menu="@menu/default_menu" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

default_menu.xml(所有用户的菜单)

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@id/homeFragment"
        android:icon="@drawable/child_selector_home"
        android:title="@string/bottom_nav_home" />

    <item
        android:id="@id/nav_shop"
        android:icon="@drawable/child_selector_shop"
        android:title="@string/bottom_nav_shop" />

    <item
        android:id="@id/userLoggedOutFragment"
        android:icon="@drawable/child_selector_profil"
        android:title="@string/bottom_nav_profil" />

</menu>

logged_in_menu

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@id/homeFragment"
        android:icon="@drawable/child_selector_home"
        android:title="@string/bottom_nav_home"/>

    <item
        android:id="@id/documentsFragment"
        android:icon="@drawable/child_selector_documents"
        android:title="@string/bottom_nav_documents"/>

    <item
        android:id="@id/nav_shop"
        android:icon="@drawable/child_selector_shop"
        android:title="@string/bottom_nav_shop"/>

    <item
        android:id="@id/shoppingCartFragment"
        android:icon="@drawable/child_selector_shopping_cart"
        android:title="@string/bottom_nav_shopping_cart" />

    <item
        android:id="@id/userLoggedInFragment"
        android:icon="@drawable/child_selector_profil"
        android:title="@string/bottom_nav_profil"/>

</menu>

活动

class MainActivity : AppCompatActivity() {
    // Basic Binding Stuff
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate()
       binding = ActivityMainBinding.inflate(layoutInflater)
       setContentView(binding.root)
   }


    @Subscribe
    fun onLoginLogOutEvent(event: LogInOutEvent) {
        if (event.isLoggedIn) signInUserBottomNav() else signOutUserBottomNav()
    }


    private fun setUpBottomNav(newMenu: Int) {
        with(binding.bottomNavigationView) {
            menu.clear()
            inflateMenu(newMenu)
            setupWithNavController(findNavController(R.id.fragment_container))
            // fix blinking when re selecting bottom nav item
            setOnNavigationItemReselectedListener {}
        }
    }

    private fun signOutUserBottomNav() {
        setUpBottomNav(R.menu.default_menu.xml)
    }

    private fun signInUserBottomNav() {
        setUpBottomNav(R.menu.logged_in_menu)
    }
}

活动

value class LogInOutEvent(
    val isLoggedIn: Boolean,)

活动执行以下操作:每次您通过事件总线从片段或活动发送事件时,onLoginOutEvent() 都会被执行。在这里,它会检查您是否发送用户登录的事件。你可以这样使用它:

某些片段

class SomeFragment : Fragment() {
   override fun onViewCreated() {
      super.onViewCreated()

   }

   private fun doStuff() {
      // here you do your stuff and decide whether to change the bottom nav or not
      Eventbus.getDefault().post(LoginOutevent(isLoggedin = true))
   }

}
,

您可以使用整个菜单项启动应用,然后根据登录用户删除项目:

这是 BottonNavigationView 的一个扩展函数,可以删除具有特定 id 的项目

fun BottomNavigationView.removeItem(id: Int) {
    if (menu.findItem(id) != null)
        menu.removeItem(id)
}

然后您可以将其应用于已登录用户:

// check logged-in user
when (loggdUser) {

    user_a -> {
        bottomNavView.removeItem(R.id.menu_item_id1)
        bottomNavView.removeItem(R.id.menu_item_id2)
    }

    user_b -> bottomNavView.removeItem(R.id.menu_item_id2)

}

menu_item_idx 应该是菜单 ID & bottomNavViewBottomNavigationView 实例;所以把它们换成你的

更新:

在代码中测试:

class DashboardActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dashboard)

        supportActionBar!!.setBackgroundDrawable(
            ContextCompat.getDrawable(
                this@DashboardActivity,R.drawable.app_gradient_color_background
            )
        )

        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
      
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_products,R.id.navigation_dashboard,R.id.navigation_orders,R.id.navigation_sold_products,R.id.navigation_orders_by_status
            )
        )
        setupActionBarWithNavController(navController,appBarConfiguration)

        navView.setupWithNavController(navController)

        
        val loggdUser = "user_a"
        // check logged-in user
        when (loggdUser) {

            "user_a" -> {
                navView.removeItem(R.id.navigation_orders_by_status)
                navView.removeItem(R.id.navigation_orders)
            }

            "user_b" -> navView.removeItem(R.id.navigation_orders)

        }

    }


    fun BottomNavigationView.removeItem(id: Int) {
        if (menu.findItem(id) != null)
            menu.removeItem(id)
    }


}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?