操作
機能 #189
未完了検温記録(JetPack Kotlin)のリファクタリング
開始日:
2020/11/20
期日:
進捗率:
80%
予定工数:
高橋 徹 さんが4年以上前に更新
検温登録日時をDataBindingsで表示させるリファクタリング¶
検温登録日時の表示(リファクタリング前)¶
- MainViewModelクラスのプロパティ measuredAt: LiveData<LocalDateTime> に検温登録日時を保持
- MainActivityクラスのonCreateメソッド内で、このプロパティにオブザーバ登録し、変化があれば LocalDateTimeを文字列化してTextViewのtextプロパティにセット
- LocalDateTimeの文字列化はハードコーディング(リソース文字列に定義した書式を参照せず)
関連する実装
- レイアウトXMLファイル(activity_main.xml)に、ビューモデル(MainViewModel)のデータ参照記述
- TextViewの拡張メソッド setMeasuredAtFormatted(item: Temperature)を定義し、レイアウトXMLファイル(item_temperature.xml)で使用
検温登録日時の表示(リファクタリング後)¶
- TextViewの拡張メソッド setMeasuredAtFormatted の修正
- 引数の型をTemperature型からLocalDateTime型へ変更
BindingUtils.kt に定義したTextViewの拡張メソッド setMeasuredAtFormatted は、RecyclerViewの個々のアイテムを表示する際に使用するので引数にTemperatureを指定していた。今回、検温登録日時の表示にも使用するが、引数がTemperature型では都合が悪いのでLocalDateTime型に変更した。 - DateTimeFormatterをローカル変数からトップレベルのプロパティとし生成を1度だけとした
+internal var formatter: DateTimeFormatter? = null @BindingAdapter("measuredAtFormatted") -fun TextView.setMeasuredAtFormatted(item: Temperature) { - val pattern = context.resources.getString(R.string.main_measured_at_format) - val formatter = DateTimeFormatter.ofPattern(pattern) - text = item.measuredAt.format(formatter) +fun TextView.setMeasuredAtFormatted(dateTime: LocalDateTime) { + if (formatter == null) { + val pattern = context.resources.getString(R.string.main_measured_at_format) + formatter = DateTimeFormatter.ofPattern(pattern) + } + text = dateTime.format(formatter) }
- 引数の型をTemperature型からLocalDateTime型へ変更
- レイアウトXMLファイル(activity_main.xml)で検温日時表示TextViewの表示設定
- app:measuredAtFormatterd属性で上述の拡張メソッド setMeasuredAtFormattedを呼ぶ。属性の値には setMeasuredAtFormattedの引数に渡す変数を指定。
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textview_main_submittitle" + app:measuredAtFormatted="@{viewModel.measuredAt}" tools:text="09.27 21:22" />
- app:measuredAtFormatterd属性で上述の拡張メソッド setMeasuredAtFormattedを呼ぶ。属性の値には setMeasuredAtFormattedの引数に渡す変数を指定。
- DataBindingでレイアウトXML内で参照するLiveData型変数の変更を表示に反映する
- MainActivityクラスのonCreateメソッドで、DataBindingの初期化時に lifecycleOwner を指定
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) + binding.lifecycleOwner = this + binding.viewModel = temperatureViewModel setContentView(binding.root)
- MainActivityクラスのonCreateメソッドで、DataBindingの初期化時に lifecycleOwner を指定
高橋 徹 さんが4年以上前に更新
検温登録操作をDataBindingsで指定するリファクタリング¶
検温登録操作(リファクタリング前)¶
- MainActivityクラスのonCreateメソッド内で、登録ボタンにクリックリスナーを設定。リスナーではNumberPickerの値(整数部、小数部)を取得し登録温度を計算し、MainViewModelクラスのsubmitTemperatureメソッドを呼び出す。
検温登録操作(リファクタリング後)¶
- MainViewModelクラスのsubmitTemperatureメソッドの引数を検温値(Float型)から、検温値整数部(Int型)および検温値小数部(Int型)に変更
⇒ 本来不要だが、レイアウトXMLの中が複雑になるので・・・(あまりよいコードではない)- fun submitTemperature(measurement: Float) { + fun submitTemperature(integral: Int, fraction: Int) {
- レイアウトXMLの中でボタンのonClick属性に式言語記載
+ android:onClick="@{() -> viewModel.submitTemperature(numberpickerMainIntegral.getValue(), numberpickerMainFraction.getValue())}"
高橋 徹 さんが4年以上前に更新
検温日時の変更をDataBindingsで行うリファクタリング¶
検温日時の変更(リファクタリング前)¶
- MainActivityクラスのonCreateメソッド内で10分前ボタンと10分後ボタンのクリックリスナーを設定。リスナーではMainViewModelのdecrementMeasuredAtメソッドおよびincrementMeasuredAtメソッドを呼び出し
検温日時の変更(リファクタリング後)¶
- レイアウトXMLの中でボタンのonClick属性に式言語で記述
+ android:onClick="@{() -> viewModel.incrementMeasuredAt(10)}" : + android:onClick="@{() -> viewModel.decrementMeasuredAt(10)}"
操作