首页 > 解决方案 > Android Studio 如何使用 Fragment 在 Kotlin 中打开日期选择器

问题描述

我尝试了一切,但似乎无法让应用程序打开日期选择器对话框。应用程序每次都崩溃。我尝试了多种解决方案,但似乎都有相同的结果。如何在片段中打开 Kotlin 中的日期选择器?

该代码在我在 Activity 类中使​​用时有效,但我希望它在 Fragment 中工作。

calendar = Calendar.getInstance()
    year = calendar.get(Calendar.YEAR)
    month = calendar.get(Calendar.MONTH)
    day = calendar.get(Calendar.DAY_OF_MONTH)
    showDate(year, month + 1, day)


fun setDate(view: View?) {
    showDialog(999)
    Toast.makeText(
        applicationContext, "Please select a date",
        Toast.LENGTH_SHORT
    )
        .show()
}

override fun onCreateDialog(id: Int): Dialog {
    return if (id == 999) {
        DatePickerDialog(
            this,
            myDateListener, year, month, day
        )
    } else onCreateDialog(1)
}

private val myDateListener =
    DatePickerDialog.OnDateSetListener { arg0, arg1, arg2, arg3 ->
        // arg1 = year
        // arg2 = month
        // arg3 = day
        showDate(arg1, arg2 + 1, arg3)
    }

/**
 * This method shows the selected date in the view
 */

private fun showDate(year: Int, month: Int, day: Int) {
    dateView.text = StringBuilder().append(day).append("/")
        .append(month).append("/").append(year)
}

showDialog() 在 Fragment 中不起作用,我尝试实现 DialogFragment 但无济于事。我该如何解决这个问题?

标签: androidandroid-studiokotlindatepickerfragment

解决方案


我认为不需要DialogFragment。尝试:

创建单独MyDatePickerDialog的类

import android.app.DatePickerDialog
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.fragment.app.FragmentActivity
import java.util.*

class MyDatePickerDialog(
    // context needed to create the dialog
    activity: FragmentActivity,
    // callback for the caller of this dialog
    onShowDateClicked: (Int, Int, Int) -> Unit
) {
    private val calendar = Calendar.getInstance()
    val year: Int
        get() = calendar.get(Calendar.YEAR)
    val month: Int
        get() = calendar.get(Calendar.MONTH)
    val day: Int
        get() = calendar.get(Calendar.DAY_OF_MONTH)

    private val dialog = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
    // on API 23 or lower, use the older constructor that requires initial date
        DatePickerDialog(
            activity,
            { _, year, month, day -> onShowDateClicked.invoke(year, month, day) },
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)
        )
    } else {
        DatePickerDialog(activity).apply {
            setOnDateSetListener { _, year, month, day ->
                onShowDateClicked.invoke(year, month, day)
            }
        }
    }
    
    fun show() {
        dialog.show()
    }
}

假设MainFragment是您要显示对话框的位置,请执行以下操作:

class MainFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // here, put correct id of the view which click event is suppose to open the dialog
        view_to_open_dialog?.setOnClickListener {
            activity?.takeIf { !it.isFinishing && !it.isDestroyed }?.let { activity ->
                MyDatePickerDialog(activity, ::showDate).show()
            }
        }
    }

    private fun showDate(year: Int, month: Int, day: Int) {
        Log.d("Picked Date", "$year-$month-$day")
        // the rest of your logic here
    }
}

推荐阅读