LocalDate.format在Observer中引起OutofBount异常。

问题描述 投票:0回答:1

我正在使用Kotlin、Material Design Components和新的架构组件在android中制作一个应用程序,我有一个活动,在创建时启动一个DialogFragment。

该片段有6个View,通过观察者,观察每个View的不同LiveDate。

当检查所有这些设置工作时,我注意到在7个视图切换后,我得到了

2020-05-12 20:43:19.346 4778-4778/package E/InputEventReceiver: Exception dispatching input event. 
2020-05-12 20:43:19.346 4778-4778/package E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback 
2020-05-12 20:43:19.357 4778-4778/package E/MessageQueue-JNI:
java.lang.ArrayIndexOutOfBoundsException: length=9; index=9
at android.text.Layout$HorizontalMeasurementProvider.get(Layout.java:1589)
...

我检查了以下事项。

  • 只在一个视图上做了所有的设置 -> 还是会崩溃。
  • 只在一个视图上做了所有的设置,但没有使用 "createDateFieldObserver "方法->仍然是车祸。
  • 没有调用观察者-> 没有崩溃。
  • 调用观察者,但不使用LocalDate.format ->没有崩溃。

我断定问题出在格式函数中,但我不明白为什么,错误不是指向那个方向,有什么想法吗?

活动代码

class UITestingActivity: FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_greenhouse)
        val dialog = LabTimesDialogFragment()
        dialog.show(supportFragmentManager, "LabTimes")
    }
}

片段代码

class TimesDialogFragment : DialogFragment() {
    companion object Companion {
        private val TAG: String = "TimesDialog"
    }
    private val datesViewModel: TimesViewModel by activityViewModels()
    private lateinit var datesViews: Map<LiveData<LocalDate>, TextInputEditText>


    override fun onCreateDialog(savedInstanceState: Bundle?) : Dialog {
        val viewsArray: Array<TextInputEditText>
        return activity?.let {
            val builder = AlertDialog.Builder(it)
            val inflater = requireActivity().layoutInflater

            val rootView: View = inflater.inflate(R.layout.dialog_filter_times, null)

            builder.setView(rootView)
                    .setPositiveButton(R.string.feed) { dialog, id -> closeDialog() }
                    .setNegativeButton(R.string.cancel) { dialog, id -> getDialog()?.cancel() }

            val dialog: AlertDialog =  builder.create()

            val fromSampling: TextInputEditText = rootView.findViewById(R.id.from_sampling) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            val toSampling: TextInputEditText = rootView.findViewById(R.id.to_sampling) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            val fromSending: TextInputEditText = rootView.findViewById(R.id.from_sending) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            val toSending: TextInputEditText = rootView.findViewById(R.id.to_sending) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            val fromReceiving: TextInputEditText = rootView.findViewById(R.id.from_receiving) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            val toReceiving: TextInputEditText = rootView.findViewById(R.id.to_receiving) ?: throw IllegalStateException("Missing date view in LabTimesFilterDialog")
            datesViews = mapOf(datesViewModel.fromSampling to fromSampling,
                    datesViewModel.toSampling to toSampling,
                    datesViewModel.fromSending to fromSending,
                    datesViewModel.toSending to toSending,
                    datesViewModel.fromReceiving to fromReceiving,
                    datesViewModel.toReceiving to toReceiving
            )
            for ((liveData, textView) in datesViews) {
                liveData.observe(this, createDateFieldObserver(textView))
                textView.setOnClickListener { v ->
                    Log.d(TAG, "hello"+v.id)
                }
            }

            return dialog
        } ?: throw IllegalStateException("Activity cannot be null")
    }

    private fun closeDialog() {
        // save dates to ViewModel
        // closeDialog
        TODO()
    }

    private fun createDateFieldObserver(tw: TextInputEditText): Observer<LocalDate> {
        return Observer { date ->
            Log.d(TAG, "obs"+tw.id)
            tw.setText(date.format(DateTimeFormatter.ISO_DATE))
            //tw.setText("hello")
        }
    }
}

查看模型

class TimesViewModel : ViewModel() {
    val fromSampling: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
    val toSampling: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
    val fromSending: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
    val toSending: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
    val fromReceiving: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
    val toReceiving: MutableLiveData<LocalDate> = MutableLiveData(LocalDate.now())
}

我已经有一段时间没有为android编程了。我在这里使用的所有东西对我来说都是新的,所以如果你在这个小代码中发现了一个反模式,我会很高兴知道。

Tnx

kotlin material-design android-livedata android-viewmodel
1个回答
0
投票

原来是因为布局的原因.视图中没有足够的空间来显示整个日期.我不明白为什么会导致indexoutofbound,但解决方案是简单地使视图 "wrap_content "或更大。

© www.soinside.com 2019 - 2024. All rights reserved.