GoogleI/Oアプリのようなフィルター機能を実装する

658634c5077d2652d14b6ba043d850f0?s=47 Umechan
December 13, 2018

 GoogleI/Oアプリのようなフィルター機能を実装する

自作アプリにてリスト表示しているデータをタグによってフィルタリングする機能を作りました。
スライド内で説明しているアプリはこちらになります。
https://play.google.com/store/apps/details?id=com.umehika.happinessbank&hl=ja

658634c5077d2652d14b6ba043d850f0?s=128

Umechan

December 13, 2018
Tweet

Transcript

  1. GoogleI/Oアプリのような フィルター機能を実装する

  2. ⾃⼰紹介 š 梅津 光(ウメツ ヒカル) š 株式会社ナビタイムジャパン 新卒⼊社 2016~ š

    Androidアプリ開発 バスNAVITIME 法⼈系アプリ š 趣味 個⼈アプリ開発 最近3つ⽬のアプリをリリースしました︕ Work Private
  3. 今⽇話すこと š フィルター機能の実装に⾄った背景 š 機能の実現⽅法 š まとめ

  4. 実装に⾄った背景

  5. 表⽰データがどんどん増えていく問題 データが増えるにつれて⾒⾟くなる フィルター機能を付けよう︕ š ⾃作アプリの機能 š 「良かったこと」を記録できる š 記録したデータはリスト表⽰かつ全件表⽰ š

    データにはタグ付け可能 登録データを⼀覧表⽰
  6. 完成イメージ GoogleI/O 2018アプリ プレイブックアプリ GoogleI/Oアプリのフィルター機能(GIF) プレイブックアプリのフィルター機能(GIF) これが作りたい︕

  7. 実現⽅法

  8. 画⾯構成 GoogleI/Oアプリのフィルター機能(GIF) Google I/Oアプリを参考に、、、 š Fragmentでリスト表⽰ š BottomSheetDialogFragment(以下BottomSheet)でタグ選択 š AndroidのBackdropは実装時点では開発途中でした

    š タグの選択状態はAACのViewModelとLiveDataで管理 š タグを選択したら即時リストを絞り込むため
  9. タグの選択状態の管理 BottomSheet Fragment ViewModelを使うことで、、、 š 別々のFragmentで同⼀インスタンスを取得可能 š MutableLiveDataをBottomSheetで変更、Fragmentで監視 š これにより絞り込みをリアクティブに表現可能

    ViewModel MutableLiveData タグを選択 変更通知
  10. ViewModelのプロパティ class FilterViewModel(useCase: UseCase) : ViewModel() { // 今回はMaterialComponentのChipを⽤いてタグ選択を⾏わせたいので、 //

    選択されたChipの位置からタグを取得するために全てのタグを持っておきます private val allTags: List<String> = useCase.getAllTag() // 選択状態を変更するためのMutableLiveData private val _selectedTags: MutableLiveData<MutableList<String>> = MutableLiveData<MutableList<String>>().apply { value = mutableListOf() } // 変更を通知するためのpublicなLiveData val selectedTags: LiveData<List<String>> = Transformations.map(_selectedTags) { it.toList() } }
  11. ViewModelのメソッド class FilterViewModel(useCase: UseCase) : ViewModel() { // Chipを選択すると位置とチェック状態が渡ってくる fun

    onCheckedChanged(index: Int, isChecked: Boolean) = if (isChecked) { val selectedTags = _selectedTags.value selectedTags.add(allTags[index]) _selectedTags.value = selectedTags } else { val selectedTags = _selectedTags.value selectedTags.remove(allTags[index]) _selectedTags.value = selectedTags } }
  12. Fragment, BottomSheetのコード // Fragment, BottomSheet両者で同じインスタンスを取得可能 viewModel = ViewModelProviders.of(targetFragment, object :

    ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel?> create(modelClass: Class<T>): T = FilterViewModel(useCase) as T }) .get(FilterViewModel::class.java) viewModel.selectedTags.observe(this, Observer { // 通知された選択されたタグでリストをフィルタリング adapter.items = filter(it) })
  13. 完成︕ š BottomSheetでタグを選択 š LiveDataの変更をリスト表⽰するFragmentが監視 š 選択されたタグでリストをフィルタリング š 動的に表⽰切り替え フィルタリングの様⼦(GIF)

  14. まとめ š タグ選択で表⽰要素を絞り込むフィルター機能を実装しました š BottomSheetで選択したタグをリスト表⽰するFragmentに通知する仕組みにしました š タグの選択状態を通知するためにAACのViewModel, LiveDataを⽤いました

  15. ご清聴ありがとうございました︕