底部导航栏浮动按钮,动作覆盖整个屏幕 - 如何做到这一点?
Bottom Navigation Bar Floating Button with action covering the whole screen - how to do this?
我有一个带有底部导航栏的 Android 应用程序。在 Main Activity 中,我有一个浮动按钮,当我按下它时,我想打开一个 Fragment(或另一个 activity?),它将覆盖整个屏幕(底部NavBar 和其他内容将在我新打开的片段下方)。我想补充一点,这个新打开的片段将用于添加一些项目,当用户填写名称、重量等所有文件并单击“添加”时,片段应该关闭,我们应该看到我们的底部导航栏它的碎片。
你能解决我的问题吗?如果有一些代码可以做到这一点,我将不胜感激!
以下是我的代码中最重要的部分:
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:
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:(我已有的其他片段都差不多)
<?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:(我已有的其他片段都差不多)
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 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:
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:
<?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:
<?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>
点击“添加”浮动操作按钮后尝试启动另一个 Activity,而不是导航到该片段。
您的新 Activity 不会像您预期的那样具有底部导航栏。
我有一个带有底部导航栏的 Android 应用程序。在 Main Activity 中,我有一个浮动按钮,当我按下它时,我想打开一个 Fragment(或另一个 activity?),它将覆盖整个屏幕(底部NavBar 和其他内容将在我新打开的片段下方)。我想补充一点,这个新打开的片段将用于添加一些项目,当用户填写名称、重量等所有文件并单击“添加”时,片段应该关闭,我们应该看到我们的底部导航栏它的碎片。
你能解决我的问题吗?如果有一些代码可以做到这一点,我将不胜感激!
以下是我的代码中最重要的部分:
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:
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:(我已有的其他片段都差不多)
<?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:(我已有的其他片段都差不多)
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 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:
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:
<?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:
<?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>
点击“添加”浮动操作按钮后尝试启动另一个 Activity,而不是导航到该片段。 您的新 Activity 不会像您预期的那样具有底部导航栏。