2019年6月15日土曜日

RecyclerView 内の TextView で textIsSelectable が効かない問題に対応する

TextView に android:textIsSelectable="true" を指定すると、TextView 長押しで文字列を選択するモードになります。

しかし RecyclerView 内の TextView にこの指定をしても、
"TextView does not support text selection. Selection cancelled."
というメッセージがログに出て、文字列を選択するモードになりません。
(問題は Android 5.0, 5.1 では起こりません。Android 6.0 以降では起こります。)

これは Android platform の既知のバグのようです。
https://code.google.com/p/android/issues/detail?id=208169

対象方法は、一度 TextView を disabled にしてから enabled にします。

https://issuetracker.google.com/issues/37095917#comment11
https://stackoverflow.com/questions/37566303/edittext-giving-error-textview-does-not-support-text-selection-selection-canc

class MainAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ... override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) { super.onViewAttachedToWindow(holder) if (holder is ViewHolder) { holder.itemView.textView.isEnabled = false holder.itemView.textView.isEnabled = true } } }


2019年5月5日日曜日

Kotlin メモ : useLines

Reader.useLines public inline fun <T> Reader.useLines(block: (Sequence<String>) -> T): T = buffered().use { block(it.lineSequence()) } val reader: Reader = ... reader.buffered().use { val sequence : Sequence<String> = it.lineSequence() ... } val reader: Reader = ... reader.useLines { val sequence : Sequence<String> = it ... }

2019年5月3日金曜日

AndroidX Preference の SummaryProvider

以下は「TechBoosterプログラミングブック ~0から学ぶ最新技術とアプリ開発テクニック~【C95新刊】」に寄稿した内容を元にしています。

-------------------

AndroidX で Preference のライブラリもアップデートされました。この Preference ライブラリを使うと、Material Design に沿った設定画面を簡単に作ることができます。

API Level 1 からある android.preference.PreferenceActivity は今では使用しません。 また、API Level 11 で追加された android.preference.PreferenceFragment は API level 28 で deprecated になっています。

設定

androidx.preference release note

最新のバージョンは 1.1.0-alpha04、stable のバージョンは 1.0.0 です。 dependencies { ... // stable は 1.0.0 implementation "androidx.preference:preference:1.1.0-alpha04" }

基本的な使い方

androidx.preference.PreferenceFragmentCompat を使います。

preference 階層を設定する方法として次の3つの方法があります。
  • XML で指定する
  • Activity の meta-data として XML を指定する
  • PreferenceScreen オブジェクトを指定する
XML で preference 階層を設定するには setPreferencesFromResource() または addPreferencesFromResource() を使います。 class SettingFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.pref, rootKey) } } 1.0.0 で PreferenceThemeOverlay がデフォルトで適用されるようになったため、カスタマイズしない場合 Preference のテーマの指定をしなくてもよくなりました。また、PreferenceThemeOverlay.v14 およびPreferenceThemeOverlay.v14.Material テーマは deprecated になっています。

Summary 機能

1.1.0-alpha01 で Summary に関係する機能が入りました。

app:useSimpleSummaryProvider

ListPreference と EditTextPreference で app:useSimpleSummaryProvider という属性を指定できるようになりました。
この属性に true を指定すると、preference の値が変わったときにその値(ListPreference の場合は対応する android:entries または android:entryValues の値)が Summary に表示されます。値が保存されていないときは "Not Set" と表示されます。 <EditTextPreference ... app:useSimpleSummaryProvider="true" /> <ListPreference ... app:useSimpleSummaryProvider="true" />
SummaryProvider

SummaryProvider を使うと、任意の Preference で値が変わったときに Summary を更新できます。

app:useSimpleSummaryProvider="true" を指定した ListPreference では ListPreference.SimpleSummaryProvider が、EditTextPreference では EditTextPreference.SimpleSummaryProvider が SummaryProvider として利用されます。

CheckBoxPreference に SummaryProvider をセットすると、チェックの状態の応じて Summary が変わるようにすることができます。 findPreference("check").setSummaryProvider { if ((it as CheckBoxPreference).isChecked) "する!" else "しない..." } いままでは以下のように起動時に Summary をセットし、さらに PreferenceChangeListener を登録して値変更時に Summary をセットするような処理が必要だったので、SummaryProvider を使うととてもシンプルにかけます。 with(findPreference("check") as CheckBoxPreference) { summary = if (isEnabled) "する!" else "しない..." setOnPreferenceChangeListener { preference, newValue -> preference.summary = if ((newValue as Boolean)) "する!" else "しない..." true } }