导航组件的默认空值:参数过多错误

Posted

技术标签:

【中文标题】导航组件的默认空值:参数过多错误【英文标题】:Default null value for navigation Component: Too many arguments error 【发布时间】:2020-09-03 05:43:00 【问题描述】:

我正在从我的片段中实现一个日期选择器。我想在我的片段上显示选定的日期。

日期选择器对话框片段:

class DatePickerDialogFragment :  DialogFragment() , DatePickerDialog.OnDateSetListener 


    @NotNull
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog 
        //return super.onCreateDialog(savedInstanceState)
        // Use the current date as the default date in the picker.
        val c: Calendar = Calendar.getInstance()
        val year: Int = c.get(Calendar.YEAR)
        val month: Int = c.get(Calendar.MONTH)
        val day: Int = c.get(Calendar.DAY_OF_MONTH)
        // Create a new instance of DatePickerDialog and return it.
        return DatePickerDialog(requireActivity(), this, year, month, day)
    


    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) 
        val selectedDate = arrayOf<String>(year.toString(),month.toString(),dayOfMonth.toString())
        val action = DatePickerDialogFragmentDirections.actionDatePickerDialogFragmentToDatePickerDemo(month.toString(),year.toString(),dayOfMonth.toString())
        //Navigation.findNavController().navigate(action)
        findNavController().navigate(action)
    

DatePickerDemo 类:

class DatePickerDemo : Fragment() ,View.OnClickListener 
    private var mSelectedMonth: String? = null
    private var mSelectedDay: String? = null
    private var mSelectedYear: String? = null
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
    

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        return inflater.inflate(R.layout.fragment_date_picker, container, false)
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        btnShowDate.setOnClickListener(this)
        arguments?.let 
            mSelectedMonth = DatePickerDemoArgs.fromBundle(it).month.toString()
            mSelectedDay = DatePickerDemoArgs.fromBundle(it).day.toString()
            mSelectedYear = DatePickerDemoArgs.fromBundle(it).year.toString()
        
        if(mSelectedMonth != null && mSelectedDay != null && mSelectedYear != null)
            processDatePickerResult(mSelectedYear!!.toInt(),mSelectedMonth!!.toInt(),mSelectedDay!!.toInt())
        
    

    override fun onClick(v: View?) 
        findNavController().navigate(R.id.datePickerDialogFragment)
    

片段和对话框片段的导航图如下:

<fragment
        android:id="@+id/datePickerDemo"
        android:name="com.kgandroid.droidcafeuimaster.DatePickerDemo"
        android:label="DatePickerDemo" >
        <action
            android:id="@+id/action_datePickerDemo_to_datePickerDialogFragment"
            app:destination="@id/datePickerDialogFragment" />
        <argument
            android:name="year"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="@null" />
        <argument
            android:name="month"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="@null" />
        <argument
            android:name="day"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="@null" />
    </fragment>
  <dialog
        android:id="@+id/datePickerDialogFragment"
        android:name="com.kgandroid.droidcafeuimaster.DatePickerDialogFragment"
        android:label="fragment_date_picker_dialog"
        tools:layout="@layout/fragment_date_picker_dialog" >
        <action
            android:id="@+id/action_datePickerDialogFragment_to_datePickerDemo"
            app:destination="@id/datePickerDemo" />
    </dialog>

问题:

很明显,当片段启动时,我不需要 DatePikerDemo 片段中的参数。当我从 DatePickerDialogFragment 返回并将其显示为 toast 时,我需要它。因此,如您所见,我在参数中添加了 null 值: app:nullable="true" android:defaultValue="@null" 在导航图中。但问题是,编译器显示错误:

public open fun actionDatePickerDialogFragmentToDatePickerDemo 的参数过多

如果没有默认值,程序正在编译但由于错误而崩溃:

 java.lang.IllegalArgumentException: Required argument "year" is missing and does not have an android:defaultValue

这很明显。那么有什么解决办法呢?

注意到在从fragment到dilogs之间通过导航库进行通信时会出现这种问题。

【问题讨论】:

【参考方案1】:

如果参数类型支持空值,您可以声明一个默认值 使用 android:defaultValue="@null"

<argument
            android:name="customer"
            app:argType="com.test.CustomerEntity"
            app:nullable="true"
            android:defaultValue="@null"/>

在出现的添加参数链接窗口中,输入参数名称, 参数类型,参数是否可以为空(app:nullable="true"), 如果需要,还有一个默认值。

https://developer.android.com/guide/navigation/navigation-pass-data

【讨论】:

以上是关于导航组件的默认空值:参数过多错误的主要内容,如果未能解决你的问题,请参考以下文章

当用户直接导航到页面时,将默认状态传递给链接

Parcelables 不支持默认值。 Android 导航深层链接参数

C#中泛型参数的空值或默认比较

laravel-5.4 - 错误:从空值创建默认对象

如何修复 PHP Strict 错误“从空值创建默认对象”?

从 PHP 中的空值创建默认对象?