【问题标题】:How to find a view for Snackbar in fragment's onCreateView method if I use view binding and navigation component?如果我使用视图绑定和导航组件,如何在片段的 onCreateView 方法中找到 Snackbar 的视图?
【发布时间】:2021-02-23 09:00:30
【问题描述】:

我试图在片段的 onCreateView 方法中显示一个小吃店,但我不知道在小吃店内传递什么视图。 我很困惑,因为我第一次使用导航组件和视图绑定,也许有问题。 我试过 binding.root 但我得到了这个异常:

java.lang.IllegalArgumentException: 找不到合适的父级 给定的看法。请提供有效的观点。

之后我尝试将 requireView().rootView 作为参数,但我也遇到了这个异常:

java.lang.IllegalStateException: 片段 XFragment{7a091b5} (cefa1aef-59c3-4602-bcf1-b36f7d538cf9) id=0x7f0800f7} 没有返回 从 onCreateView() 查看或在 onCreateView() 之前调用它

我在 XFragment 中的代码:

package com.sdsd.sds

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.Navigation
import com.google.android.material.snackbar.Snackbar

import com.sdsd.sds.databinding.FragmentXBinding

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"


class XFragment : Fragment() {

    private var _binding: FragmenXBinding? = null
    private val binding get() = _binding!!


    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentXBinding.inflate(inflater, container, false)
        binding.tvFgRegistration.setOnClickListener {
            Navigation.findNavController(binding.root)
                .navigate(R.id.action_f1_to_f2)
        }

        

        val snackbar: Snackbar = Snackbar.make(binding.root, "Succesful", Snackbar.LENGTH_LONG)
        snackbar.show()


        return binding.root
    }

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


    companion object {

        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            XFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

XML LAYOUT FILE:

    <?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"
        android:background="@drawable/ic"
        tools:context=".XFragment">
    
       
        <EditText
            android:id="@+id/etE"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:background="@color/translucent"
            android:drawableStart="@drawable/ic_vector"
            android:drawablePadding="5dp"
            android:ems="10"
            android:hint="@string/e_mail"
            android:inputType="text"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />
    
        <EditText
            android:id="@+id/etP"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:background="@color/translucent"
            android:drawableStart="@drawable/ic_vector"
            android:drawablePadding="5dp"
            android:ems="10"
            android:hint="@string/password"
            android:inputType="textPassword"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/etE" />
    
          
        <TextView
            android:id="@+id/tvFgRegistration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="180dp"
            android:layout_marginEnd="76dp"
            android:layout_marginBottom="100dp"
            android:text="@string/new_u"
            android:textColor="@color/white"
            android:textSize="18sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

我只想在 XFragment 创建时显示带有消息的小吃店。

谁能告诉我如何解决这个问题并用几句话解释为什么?

【问题讨论】:

  • 尝试返回 _binding 或 binding(不带 .root)

标签: kotlin android-fragments android-architecture-navigation android-snackbar android-viewbinding


【解决方案1】:

我找到了一个简单的解决方案,而且似乎 Snackbar 效果很好只有将 CoordinatorLayout 作为根布局,所以我在 XML 文件中将 CoordinatorLayout 设置为我的根布局。

在 Snackbar 中,我只是将 binding.coordinatorlayout 放在其中 coordinatorlayout 只是 XML 文件中 CoordinatorLayout 的一个 id。

片段的代码解决方案在这里:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentXBinding.inflate(inflater, container, false)
        binding.tvFgRegistration.setOnClickListener {
            Navigation.findNavController(binding.root)
                .navigate(R.id.action_f1_to_f2)
        }

        val snackbar: Snackbar = Snackbar.make(binding.coordinatorlayout, "Succesful", Snackbar.LENGTH_LONG)
        snackbar.show()


        return binding.root
    }

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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorlayout" //ID OF COORDINATOR LAYOUT
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic"
    tools:context=".XFragment" >

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic_backg">

  <EditText
            android:id="@+id/etE"
            android:layout_width="0dp"
      .
      .
      .


</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

【讨论】:

    【解决方案2】:

    我发现了几种从片段中显示小吃店的方法

    其中一个解决方案是使用 requireView()

    Snackbar.make(
                requireView(),
                "Hello from Snackbar",
                Snackbar.LENGTH_SHORT
            ).show()
    

    当您在任何 onClickListner{} 中时,此解决方案将起作用,您只需将 作为视图传递,它就会完成这项工作。

        binding.button.setOnClickListener {
           Snackbar.make(
                    it,
                    "Hello from Snackbar",
                    Snackbar.LENGTH_SHORT
                ).show()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多