2019年10月8日火曜日

Master of Dagger の正誤表

技術書典7で出した「Master of Dagger」の正誤表です。

10章 10.1 ViewModel




Androidにはリソースが足りなくなったときにフレームワークがしばらく使われていないActivityを破棄し、あとでそのActivityが必要になったときに再生成する仕組みがあります。
Activityでデータを持っていると、Activityが破棄されるときに一緒に消えてしまうため、サーバーから再度取得したり、破棄されるときにデータを保存して再生成時にリストアする処理が必要になります。
ViewModelはこの破棄・再生成時のデータ保存処理を楽にしてくれます。ViewModelはActivityの再生成を超えてインスタンスが保持される仕組みになっており、ViewModelでデータを持っておけば破棄・再生成後も以前のデータにアクセスできます。



AndroidではConfigurationが変わったときにActivityを破棄して作り直す仕組みがあります。Configurationには画面の向きや言語設定や画面サイズなどがあり、Activityを作り直す仕組みによって新しいConfigurationに最適なレイアウトや文字列リソースで画面が作られます。
しかしActivityで保持していたデータは画面回転などConfigurationの変更によってActivityが再生成されるときに消えてしまいます。そのため再度データを取得したり、Activityが破棄されるときにデータを保存して再生成時にリストアする処理が必要になります。ViewModelはこのデータの引き継ぎ処理を楽にしてくれます。
ViewModelはConfigurationの変更によるActivityの再生成を超えてインスタンスが保持される仕組みになっており、ViewModelにデータを持たせるようにすれば、再生成後のActivityからも以前のデータにアクセスすることができます。



13章 13.1 Android で Dagger を使うときの問題点




ボイラーブレート



ボイラープレート



2章 2.1 Dagger とは




*2 Dagger 1はリフレクションベースの動的DIフレームワークでした



削除 (Dagger 1では一部リフレクション使った機能がありました)



2019年9月5日木曜日

Kotlin メモ : count

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/count.html


大文字数を数えるダメな例 val String.upperCaseCount: Int get() = filter { it.isUpperCase() }.length

大文字数を数える良い例 val String.upperCaseCount: Int get() = count { it.isUpperCase() }

2019年8月6日火曜日

AlertDialog の Negative ボタンの文字色を変える

AndroidX の AlertDialog で Negative ボタンと Positive ボタンを出すと、両方文字が colorAccent の色になります。 import androidx.appcompat.app.AlertDialog class SampleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_sample) button.setOnClickListener { AlertDialog.Builder(this) .setMessage("メッセージ") .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(android.R.string.ok, null) .show() } } }

Negative ボタンの文字色を変えるには Widget.AppCompat.Button.ButtonBar.AlertDialog を継承した style を用意し、android:textColor を指定します。 <style name="Widget.Sample.Button.ButtonBar.AlertDialog.Negative" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> <item name="android:textColor">?android:attr/textColorSecondary</item> </style> ThemeOverlay.AppCompat.Dialog.Alert を継承したテーマを用意し、その中で buttonBarNegativeButtonStyle に上で定義した style を指定します。 <style name="ThemeOverlay.Sample.Dialog.Alert" parent="ThemeOverlay.AppCompat.Dialog.Alert"> <item name="buttonBarNegativeButtonStyle">@style/Widget.Sample.Button.ButtonBar.AlertDialog.Negative</item> </style> 用意したテーマを AlertDialog.Builder のコンストラクタで指定するか AlertDialog.Builder(this, R.style.ThemeOverlay_Sample_Dialog_Alert) .setMessage("メッセージ") .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(android.R.string.ok, null) .show() alertDialogTheme に指定します。 <style name="Theme.Sample.Light" parent="Theme.AppCompat.Light"> <item name="alertDialogTheme">@style/ThemeOverlay.Sample.Dialog.Alert</item> </style>


AppCompat の設定と解説

alertDialogStyle に指定されている AlertDialog.AppCompat をたどっていくと、 <style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat"> … <item name="alertDialogStyle">@style/AlertDialog.AppCompat</item> </style> <style name="AlertDialog.AppCompat" parent="Base.AlertDialog.AppCompat"/> <style name="Base.AlertDialog.AppCompat" parent="android:Widget"> <item name="android:layout">@layout/abc_alert_dialog_material</item> <item name="listLayout">@layout/abc_select_dialog_material</item> <item name="listItemLayout">@layout/select_dialog_item_material</item> <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_material</item> <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_material</item> <item name="buttonIconDimen">@dimen/abc_alert_dialog_button_dimen</item> </style> layout に @layout/abc_alert_dialog_material が指定されています。この中で button bar 部分は @layout/abc_alert_dialog_button_bar_material に分割されています。

これを見ると Negative Button には style="?attr/buttonBarNegativeButtonStyle" が指定されていることがわかります。

@layout/abc_alert_dialog_button_bar_material <ScrollView …> <android.support.v7.widget.ButtonBarLayout …"> … <Button android:id="@android:id/button2" style="?attr/buttonBarNegativeButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@android:id/button1" style="?attr/buttonBarPositiveButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </android.support.v7.widget.ButtonBarLayout> </ScrollView> buttonBarNegativeButtonStyle には buttonBarButtonStyle が指定されており、buttonBarButtonStyle には Widget.AppCompat.Button.ButtonBar.AlertDialog が指定されています。 <style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat"> … <item name="buttonBarButtonStyle">@style/Widget.AppCompat.Button.ButtonBar.AlertDialog</item> <item name="buttonBarPositiveButtonStyle">?attr/buttonBarButtonStyle</item> <item name="buttonBarNegativeButtonStyle">?attr/buttonBarButtonStyle</item> <item name="buttonBarNeutralButtonStyle">?attr/buttonBarButtonStyle</item> </style> Widget.AppCompat.Button.ButtonBar.AlertDialog は最終的に Widget.AppCompat.Button.Borderless.Colored を継承しており、これによりボタンの文字が colorAccent 色になっています。 <style name="Widget.AppCompat.Button.ButtonBar.AlertDialog" parent="Base.Widget.AppCompat.Button.ButtonBar.AlertDialog"/> <style name="Base.Widget.AppCompat.Button.ButtonBar.AlertDialog" parent="Widget.AppCompat.Button.Borderless.Colored"> <item name="android:minWidth">64dp</item> <item name="android:minHeight">@dimen/abc_alert_dialog_button_bar_height</item> </style> Widget.AppCompat.Button.ButtonBar.AlertDialog を継承した style を用意し、文字色を上書きして buttonBarButtonStyle にセットすれば Negative Button の文字色を変えることができます。