You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android/Kotlin 如何实现DialogFragment向Fragment传递数据

Android DialogFragment向父Fragment传值实现方案

针对你的需求,这里提供两种可直接落地的实现方式,均基于你现有代码修改:


方案1:接口回调实现(适合简单传值场景,逻辑直观)

步骤1:修改TimePickerFragment.kt,定义回调接口

package com.example.mytablayout.fragments

import android.app.Dialog
import android.app.TimePickerDialog
import android.content.Context
import android.os.Bundle
import android.text.format.DateFormat
import android.widget.TimePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class TimePickerFragment: DialogFragment(), TimePickerDialog.OnTimeSetListener {
    // 定义时间选择回调接口
    interface OnTimeSelectedListener {
        fun onTimeSelected(hour: Int, minute: Int)
    }

    private lateinit var listener: OnTimeSelectedListener

    // Fragment绑定上下文时获取父Fragment的回调实例
    override fun onAttach(context: Context) {
        super.onAttach(context)
        // 你是通过Weight的childFragmentManager启动弹窗,所以parentFragment就是Weight实例
        listener = parentFragment as OnTimeSelectedListener
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY) // 这里建议用HOUR_OF_DAY避免12小时制问题
        val minute = c.get(Calendar.MINUTE)
        return TimePickerDialog(requireActivity(), this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(view: TimePicker, hour: Int, minute: Int) {
        // 选中时间后触发回调,把值传给父Fragment
        listener.onTimeSelected(hour, minute)
    }
}

步骤2:修改Weight.kt,实现回调接口更新按钮

注意:你原代码中把btnTime声明为全局变量会有内存泄漏风险,建议移到类内部作为私有成员

package com.example.mytablayout

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import com.example.mytablayout.fragments.TimePickerFragment
import java.util.*

class Weight : Fragment(), TimePickerFragment.OnTimeSelectedListener {
    // 把按钮声明移到类内部
    private lateinit var btnTime: Button

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY)
        val minute = c.get(Calendar.MINUTE)

        btnTime = view.findViewById(R.id.btnTime)
        btnTime.text = String.format("%02d:%02d", hour, minute)

        btnTime.setOnClickListener {
            val newTimeFragment = TimePickerFragment()
            newTimeFragment.show(childFragmentManager, "timePicker")
        }
    }

    // 实现回调接口,接收选中的时间更新按钮
    override fun onTimeSelected(hour: Int, minute: Int) {
        btnTime.text = String.format("%02d:%02d", hour, minute)
    }
}

方案2:ViewModel实现(适合复杂场景,配置变更不丢失数据)

如果你的项目后续有更复杂的数据共享需求,推荐用ViewModel实现,无需写回调接口。

步骤1:新建共享ViewModel类TimeViewModel.kt

package com.example.mytablayout

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class TimeViewModel : ViewModel() {
    private val _selectedTime = MutableLiveData<String>()
    val selectedTime: LiveData<String> = _selectedTime

    fun updateTime(hour: Int, minute: Int) {
        _selectedTime.value = String.format("%02d:%02d", hour, minute)
    }
}

步骤2:修改TimePickerFragment.kt,选中时间后更新ViewModel

override fun onTimeSet(view: TimePicker, hour: Int, minute: Int) {
    // 获取和父Fragment共享的ViewModel实例
    val timeViewModel = ViewModelProvider(requireParentFragment())[TimeViewModel::class.java]
    timeViewModel.updateTime(hour, minute)
}

步骤3:修改Weight.kt,观察ViewModel数据更新按钮

class Weight : Fragment() {
    private lateinit var btnTime: Button
    // 初始化当前Fragment作用域的ViewModel
    private val timeViewModel: TimeViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // ...原有初始化代码不变

        // 观察时间变化自动更新按钮
        timeViewModel.selectedTime.observe(viewLifecycleOwner) { timeStr ->
            btnTime.text = timeStr
        }

        btnTime.setOnClickListener {
            val newTimeFragment = TimePickerFragment()
            newTimeFragment.show(childFragmentManager, "timePicker")
        }
    }
}

内容的提问来源于stack exchange,提问作者MZX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 04:06:04