简体   繁体   English

底部导航栏浮动按钮,动作覆盖整个屏幕 - 如何做到这一点?

[英]Bottom Navigation Bar Floating Button with action covering the whole screen - how to do this?

I have an Android application with Bottom Navigation Bar.我有一个带有底部导航栏的 Android 应用程序。 In the Main Activity I have a floating button and when I press it, I would like to open a Fragment (or another activity?) that will cover the whole screen (the Bottom NavBar and other content will be below my new opened fragment) .在主活动中,我有一个浮动按钮,当我按下它时,我想打开一个片段(或另一个活动?),它将覆盖整个屏幕(底部导航栏和其他内容将在我新打开的片段下方) I would like to add that this newly opened fragment will be used for adding some item and when the user fills all fileds like name, weight etc. and click "add", the fragment should be closed and we should see our bottom nav bar with its' fragments.我想补充一点,这个新打开的片段将用于添加一些项目,当用户填写名称、体重等所有文件并单击“添加”时,片段应该关闭,我们应该看到底部导航栏它的碎片。

Could you provide the solution to my problem?你能提供我的问题的解决方案吗? I would be grateful for some code enabling to do this!我将不胜感激一些代码能够做到这一点!

Here are the most important parts of my code:以下是我的代码中最重要的部分:

activity_main.xml: activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

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

    <fragment
        android:id="@+id/nav_host_fragment_activity_main"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0"
        app:navGraph="@navigation/mobile_navigation" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/buttonAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="84dp"
        android:contentDescription="@string/add_button"
        android:src="@drawable/ic_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt: MainActivity.kt:

package com.example.myapp

import android.os.Bundle
import android.view.View
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.myapp.databinding.ActivityMainBinding
import com.example.myapp.ui.AddProductFragment
import com.google.android.material.snackbar.Snackbar

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val navView: BottomNavigationView = binding.navView

        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(setOf(
                R.id.navigation_expiring, R.id.navigation_storages, R.id.navigation_notifications))
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)

        // floating button:
        val buttonAdd: View = findViewById(R.id.buttonAdd)
        buttonAdd.setOnClickListener {
            //navigate(R.id.action_login_to_registration)
            //view.findNavController().navigate(R.id.actionAddProduct)
            supportFragmentManager
                .beginTransaction().add(R.id.nav_host_fragment_activity_main, AddProductFragment())
                .commit()
        }
    }
}

fragment_storages.xml: (other fragments I already have are almost the same) fragment_storages.xml:(我已经拥有的其他片段几乎相同)

<?xml version="1.0" encoding="utf-8"?>
<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=".ui.storages.StoragesFragment">

    <TextView
        android:id="@+id/text_dashboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

StoragesFragment.kt: (other fragments I already have are almost the same) StoragesFragment.kt:(我已经拥有的其他片段几乎一样)

package com.example.myapp.ui.storages

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.myapp.databinding.FragmentStoragesBinding

class StoragesFragment : Fragment() {

    private var _binding: FragmentStoragesBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        val dashboardViewModel =
                ViewModelProvider(this).get(StoragesViewModel::class.java)

        _binding = FragmentStoragesBinding.inflate(inflater, container, false)
        val root: View = binding.root

        val textView: TextView = binding.textDashboard
        dashboardViewModel.text.observe(viewLifecycleOwner) {
            textView.text = it
        }
        return root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

fragment_add_product.xml:片段添加产品.xml:

<?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"
    tools:context=".ui.AddProductFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Add Product Fragment" />

</androidx.constraintlayout.widget.ConstraintLayout>

AddProductFragment.kt: AddProductFragment.kt:

package com.example.myapp.ui

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.myapp.R

class AddProductFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_add_product, container, false)
    }
}

bottom_nav_menu.xml: 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_expiring"
        android:icon="@drawable/ic_expiring"
        android:title="@string/title_expiring" />

    <item
        android:id="@+id/navigation_storages"
        android:icon="@drawable/ic_storages"
        android:title="@string/title_storages" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />

</menu>

mobile_navigation.xml: 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_expiring">

    <fragment
        android:id="@+id/navigation_expiring"
        android:name="com.example.myapp.ui.expiring.ExpiringFragment"
        android:label="@string/title_expiring"
        tools:layout="@layout/fragment_expiring" >
    </fragment>

    <fragment
        android:id="@+id/navigation_storages"
        android:name="com.example.myapp.ui.storages.StoragesFragment"
        android:label="@string/title_storages"
        tools:layout="@layout/fragment_storages" />

    <fragment
        android:id="@+id/navigation_notifications"
        android:name="com.example.myapp.ui.notifications.NotificationsFragment"
        android:label="@string/title_notifications"
        tools:layout="@layout/fragment_notifications" />

    <fragment
        android:id="@+id/navigation_add_product"
        android:name="com.example.myapp.ui.AddProductFragment"
        android:label="Add product"
        tools:layout="@layout/fragment_notifications" />

</navigation>

Instead of navigating to the fragment, try to start another Activity after clicking "Add" floating action button.不要导航到片段,而是在单击“添加”浮动操作按钮后尝试启动另一个 Activity。 Your new Activity will not have bottom navigation bar as you expected.您的新活动不会像您预期的那样有底部导航栏。

I have a solution.我有一个解决方案。 It worked for me.它对我有用。 First, you just write this code in your activity where BottomNavigationView is located.首先,您只需在 BottomNavigationView 所在的 Activity 中编写此代码。

MainActivity.xml MainActivity.xml

 binding.fab.setOnClickListener(object : View.OnClickListener {
        override fun onClick(view: View) {
            binding.bottomNavigationView.selectedItemId = R.id.nav_cards
            navController.navigate(R.id.nav_cards)
        }
    })
    binding.bottomNavigationView.setOnItemSelectedListener {
        when (it.itemId) {
            R.id.nav_home -> {
                navController.navigate(R.id.nav_home)
                true
            }
            R.id.nav_book -> {
                navController.navigate(R.id.nav_book)
                true
            }
            R.id.nav_bookmark -> {
                navController.navigate(R.id.nav_bookmark)
                true
            }
            R.id.nav_settings -> {
                navController.navigate(R.id.nav_settings)
                true
            }
            else -> false
        }
    }

After that, you should use onBackPressed function.之后,您应该使用 onBackPressed function。 Otherwise, you may appear another problem which belongs to collecting backStacks.否则,您可能会出现另一个属于收集 backStacks 的问题。

  override fun onBackPressed() {
    if (binding.bottomNavigationView.selectedItemId == R.id.nav_home) {
        binding.bottomNavigationView.selectedItemId = R.id.nav_home
        super.onBackPressed()
        finish()
    } else {
        binding.bottomNavigationView.selectedItemId = R.id.nav_home
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM