Home » Android » android – Variable accesability between RecycleViewAdapter and TimePickerFragment-Exceptionshub

android – Variable accesability between RecycleViewAdapter and TimePickerFragment-Exceptionshub

Posted by: admin February 26, 2020 Leave a comment

Questions:

I am working on a list of time ranges in which user can choose time using TimePickerFragment. My list is RecyclerView and below is its adapter. My problem is the inability to change the data class value (TimeRange is simple class that comprises two strings: var from and var to) from scope of TimePickerFragment. TextView responsible for time pick visualization works as I expect. Both variables are passed in TimePickerFragment constructor that is how I want them to be set when picker’s onTimeSet().

I did some tests and the following code results in setting data class with value of adapter_scope instead of ‘fragment_scope.’

Surely I don’t understand some aspect of Android programming and fragments architecture, that’s why I kindly ask for some help and explaining what logic stays behind it.

class TimeRangesAdapter(private val timeRanges: MutableList<TimeRange>) :
    RecyclerView.Adapter<TimeRangesAdapter.TimeRangesViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeRangesViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val scheduleTimeRangeBinding = ScheduleTimeRangeBinding.inflate(inflater, parent, false)
        return TimeRangesViewHolder(scheduleTimeRangeBinding)
    }

    override fun getItemCount(): Int = timeRanges.size

    override fun onBindViewHolder(holder: TimeRangesViewHolder, position: Int) {
        holder.apply {
            setIsRecyclable(false)
            bind(timeRanges[position])
        }
    }

    class TimeRangesViewHolder(private val scheduleTimeRangeBinding: ScheduleTimeRangeBinding) :
        RecyclerView.ViewHolder(scheduleTimeRangeBinding.root) {

        fun bind(scheduleTimeRange: TimeRange) {
            setListenersForTimePickers(
                scheduleTimeRangeBinding, scheduleTimeRangeBinding.root,
                scheduleTimeRange
            )

            scheduleTimeRangeBinding.startTime = scheduleTimeRange.from
            scheduleTimeRangeBinding.stopTime = scheduleTimeRange.to
            scheduleTimeRangeBinding.executePendingBindings()
        }

        private fun setListenersForTimePickers(
            scheduleTimeRangeBinding: ScheduleTimeRangeBinding,
            parent: View, timeRange: TimeRange
        ) {
            scheduleTimeRangeBinding.scheduleStartTime.setOnClickListener {
                TimePickerFragment(
                    scheduleTimeRangeBinding.scheduleStartTime,
                    timeRange.from
                ).show(
                    (parent.context as RoomActivity).supportFragmentManager,
                    "timePicker"
                )
                timeRange.from = "adapter_scope"
            }
            scheduleTimeRangeBinding.scheduleStopTime.setOnClickListener {
                TimePickerFragment(
                    scheduleTimeRangeBinding.scheduleStopTime,
                    timeRange.to
                ).show(
                    (parent.context as RoomActivity).supportFragmentManager,
                    "timePicker"
                )
                timeRange.to = "adapter_scope"
            }
        }
    }

    class TimePickerFragment(private val textView: TextView, private var date: String?) :
        DialogFragment(),
        TimePickerDialog.OnTimeSetListener {

        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
            val c = Calendar.getInstance()
            val hour = c.get(Calendar.HOUR_OF_DAY)
            val minute = c.get(Calendar.MINUTE)

            return TimePickerDialog(
                activity,
                this,
                hour,
                minute,
                true
            )
        }

        @SuppressLint("SetTextI18n")
        override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) {
            val min = if (minute < 10) "0$minute" else "$minute"

            textView.text = "$hourOfDay:$min"
            date = "fragment_scope"
        }
    }
}
How to&Answers: