• トップ
  • ブログ一覧
  • 【Android】備忘録その1(LiveData)
  • 【Android】備忘録その1(LiveData)

    えばたん(エンジニア)えばたん(エンジニア)
    2022.05.17

    IT技術

    LiveDataの値がDataBindingのLayoutに反映されない

    Androidの勉強や実装中に気づいたこと忘れそうなことを自分用の備忘録として残していきたい。

    初回はLiveDataを使うときに毎回忘れてしまって時間を無駄にすることを残しておく。

    だいたいLifecycleOwnerの設定忘れている。

    新規画面実装でよく忘れる。

    1class MyFragment() : Fragment() {
    2    private lateinit var binding: FragmentLayoutBinding
    3    override fun onViewCreated(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    4        binding = FragmentLayoutBinding.inflate(inflater, container, false)
    5        // ↓これを毎回忘れる↓
    6        binding.lifecycleOwner = viewLifecycleOwner // Activityはthis
    7        binding.vm = viewModel // ←当然Modelの設定忘れてはいけない
    8        return binding.root
    9    }
    10}

    LiveDataの型と初期値は意識したほうがいい

    気にしていないとハマる。

    LiveDataの初期値はなるべく設定しておいたほうが不具合入り込みにくい気がする。

    よくやってしまうのが処理結果をLiveDataで保持する場合↓ような持ち方をしてしまう。

    1val resultModelLiveData = MutableLiveData<ResultModel>()

    これだと初期値の設定がしづらい。

    初期値の設定がなくても実装できるが、画面のリセットがある実装やMediatorLiveData発火元の(addSoruceに追加する)LiveDataにする場合に、どうしても無理をした実装になってしまう。

    また、「DroidKaigi2020アプリのcombine」を使う場合も、初期値があったほうが都合がいいことが多い(初期値がないとblockが実行されない実装になっているので)

    解決方法は「ありえる状態をすべて表せるようにする」

    以下のようなクラスをつくりラッピングして持つと扱いやすい。

    1sealed class Status<out T> {
    2    object None: Status<Nothing>()
    3    object Loading: Status<Nothing>()
    4    object Canceled: Status<Nothing>() // ←Noneがあるので不要かもしれない
    5    class Succeeded<out T>(val value: T): Status<T>()
    6    class Failed(val e: Exception): Status<Nothing>()
    7}

    (「Status」という名前でいいのかなぁ…もっといい名前ないかなという問題は残っている)

    1val resultModelLiveData = MutableLiveData<Status<ResultModel>>(Status.None)

    ↑のように初期値を表現できて、使いやすくて分かりやすいのでよき

    他の解決策も一応ある

    型をnullableにするのもアリですが場合によるかなぁと。nullが何を示しているか分かりづらいときもあるので、ラッピングする選択肢があることを忘れたくはない。

    えばたん(エンジニア)

    えばたん(エンジニア)

    おすすめ記事