当前位置: 首页 > 知识库问答 >
问题:

如何根据在Kotlin中选择的片段显示/隐藏FloatingActionButton?

夏烨霖
2023-03-14

我有一个带有底部导航视图、浮动操作按钮和四个片段的活动。我只想在“fragment1”和“fragment2”上显示浮动操作按钮,并在选择“fragment3”或“fragment4”时将其隐藏。启动应用程序时,“fragment1”会显示为浮动操作按钮,当我导航到“fragment3”时,我设法将其隐藏起来。但问题是,当我从“fragment3”或“fragment4”导航回“fragment1”时,浮动操作按钮仍然隐藏。

以下是我的“HomeActivity”的xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottom_appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/nav_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="16dp"
            android:background="@android:color/transparent"
            app:menu="@menu/bottom_nav_menu" />

    </com.google.android.material.bottomappbar.BottomAppBar>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_hide_category"
            app:layout_anchor="@id/bottom_appbar"/>

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="50dp"
        app:defaultNavHost="true"
        app:navGraph="@navigation/mobile_navigation"
        app:layout_anchor="@id/bottom_appbar"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

下面是我在“HomeActivity”中的代码,我从片段的创建视图调用它来隐藏它。

fun hideFabOne(){
    binding.fabOne.hide()
}

然后我在“HomeActivity”中添加下面的代码,并从片段中调用它,以显示FAB,应用程序在启动时崩溃。

fun showFabOne(){
    binding.fabOne.show()
}

编辑:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.abc.xyz/com.abc.xyz.ui.activities.HomeActivity}: android.view.InflateException: Binary XML file line #112 in com.abc.xyz:layout/activity_home: Binary XML file line #112 in com.abc.xyz:layout/activity_home: Error inflating class fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3835)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: android.view.InflateException: Binary XML file line #112 in com.abc.xyz:layout/activity_home: Binary XML file line #112 in com.abc.xyz:layout/activity_home: Error inflating class fragment
     Caused by: android.view.InflateException: Binary XML file line #112 in com.abc.xyz:layout/activity_home: Error inflating class fragment
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
        at com.abc.xyz.ui.activities.HomeActivity.showFabOne(HomeActivity.kt:110)
        at com.abc.xyz.ui.fragments.HomeFragment.onCreateView(HomeFragment.kt:102)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
        at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
        at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
        at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
        at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
        at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
        at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
        at com.abc.xyz.databinding.ActivityHomeBinding.inflate(ActivityHomeBinding.java:59)
        at com.abc.xyz.databinding.ActivityHomeBinding.inflate(ActivityHomeBinding.java:53)
        at com.abc.xyz.ui.activities.HomeActivity.onCreate(HomeActivity.kt:38)
2021-11-10 11:23:40.557 13300-13300/com.abc.xyz E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:8207)
        at android.app.Activity.performCreate(Activity.java:8191)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

共有2个答案

田昊天
2023-03-14

我重用了代码并将您的XML添加到我的XML文件中。

原因是什么

我在不同的方法中添加了一些日志来检查调用顺序以查找崩溃原因。

我的解决方案是:将代码移动到片段中的onResume方法

这是我的代码主活动

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    lateinit var fab: FloatingActionButton

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("MainActivity", "TANCOLO===> onCreate 000 ")

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

        val navView: BottomNavigationView = binding.navView
        fab = findViewById(R.id.fab_one)
        Log.d("MainActivity", "TANCOLO===> onCreate 111, fab = $fab ")

        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

家庭片段

class HomeFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel
    private var _binding: FragmentHomeBinding? = 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? {
        Log.d("HomeFragment", "TANCOLO===> onCreateView() ")
        homeViewModel =
            ViewModelProvider(this).get(HomeViewModel::class.java)

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

        val textView: TextView = binding.textHome
        homeViewModel.text.observe(viewLifecycleOwner, Observer {
            textView.text = it
        })
        return root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d("HomeFragment", "TANCOLO===> onViewCreated  ")

        //get the FAB and show it.
//        (requireActivity() as MainActivity).fab.apply {
//            Log.d("HomeFragment", "TANCOLO===> onViewCreated, fab = $this  ")
//            visibility = View.VISIBLE
//        }
    }

    override fun onResume() {
        super.onResume()
        Log.d("HomeFragment", "TANCOLO===> onResume  ")
        //get the FAB and show it.
        (requireActivity() as MainActivity).fab.apply {
            Log.d("HomeFragment", "TANCOLO===> onResume, fab = $this  ")
            visibility = View.VISIBLE // or View.GONE
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
黄俊智
2023-03-14

由于您使用的是app:navGraph,请使用addOnDestinationChangedListener来控制浮动操作按钮的可见性。

HomeActive内部执行此操作

navController.addOnDestinationChangedListener { _, destination, _ ->
    if(destination.id == /*FRAGMENT ID*/) {
        // hide
    } else {
        // show
    }
}
 类似资料:
  • 我正在开发包含2个片段的应用程序,我想根据需要显示隐藏。下面的代码有一个简单的例子来说明我的问题。这个简单的Fragmentactivity包含一个按钮和一个listfragment。 这个简单的例子完美无瑕。但我不满足于展示隐藏片段。如果删除布局。设置可见性(View.GONE);然后从代码中选择ft.hide(f);不会隐藏碎片。事实上,我们不是在隐藏片段,而是在隐藏容器。 我的问题是,这是一

  • 我的p:dataTable是这样设置的。 感谢任何帮助

  • 问题内容: 我试图根据我选择的字段之一的值显示和隐藏一些表单字段。我希望使用数组来保存每个选择值应显示的内容和不应该显示的内容,以免将我从庞大的switch语句中删除,但无法弄清楚该如何做。 我正在使用PHP和jQuery。任何帮助都会很棒。 问题答案: 尝试这样的事情: 然后在jQuery中:

  • 我试图从活动中隐藏/显示片段中的按钮,但它给了我以下异常。 android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。 家庭活动 类别片段 代码太大,无法在此处发布。这就是为什么我只在发现问题的地方发布代码。 我能够获得新设计按钮实例。令我震惊的是,如果尝试玩按钮实例(可见/消失),它会给我上述异

  • 我有两个<代码> 当用户从第一个选择框中选择一个值时,我希望第二个选择框只显示连接的值。 我的代码: 因此,当用户从第一个选择框M中选择“test1”时,他在第二个选择框上只会看到“test2”、“test3”和“test4”;第一个框中的“test2”将在第二个框中显示“test6”、“test7”和“test8”。 如何使用JavaScript解决此问题?

  • 有很多关于查找显示/隐藏软键盘事件的帖子。我发现自己的处境是,我需要根据软键状态在片段中更改图标。 我试图实现onMeasure,但我无法在片段中覆盖它。是否有一种(相对)无痛的方式可以在我的片段中获得清晰的显示/隐藏软键盘事件,或者我应该放弃?