Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

umechanhika
December 13, 2018

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

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

umechanhika

December 13, 2018
Tweet

More Decks by umechanhika

Other Decks in Programming

Transcript

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

    View Slide

  2. ⾃⼰紹介
    š 梅津 光(ウメツ ヒカル)
    š 株式会社ナビタイムジャパン
    新卒⼊社 2016~
    š Androidアプリ開発
    バスNAVITIME
    法⼈系アプリ
    š 趣味
    個⼈アプリ開発
    最近3つ⽬のアプリをリリースしました︕
    Work
    Private

    View Slide

  3. 今⽇話すこと
    š フィルター機能の実装に⾄った背景
    š 機能の実現⽅法
    š まとめ

    View Slide

  4. 実装に⾄った背景

    View Slide

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

    View Slide

  6. 完成イメージ
    GoogleI/O 2018アプリ プレイブックアプリ
    GoogleI/Oアプリのフィルター機能(GIF) プレイブックアプリのフィルター機能(GIF)
    これが作りたい︕

    View Slide

  7. 実現⽅法

    View Slide

  8. 画⾯構成
    GoogleI/Oアプリのフィルター機能(GIF)
    Google I/Oアプリを参考に、、、
    š Fragmentでリスト表⽰
    š BottomSheetDialogFragment(以下BottomSheet)でタグ選択
    š AndroidのBackdropは実装時点では開発途中でした
    š タグの選択状態はAACのViewModelとLiveDataで管理
    š タグを選択したら即時リストを絞り込むため

    View Slide

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

    View Slide

  10. ViewModelのプロパティ
    class FilterViewModel(useCase: UseCase) : ViewModel() {
    // 今回はMaterialComponentのChipを⽤いてタグ選択を⾏わせたいので、
    // 選択されたChipの位置からタグを取得するために全てのタグを持っておきます
    private val allTags: List = useCase.getAllTag()
    // 選択状態を変更するためのMutableLiveData
    private val _selectedTags: MutableLiveData> =
    MutableLiveData>().apply { value = mutableListOf() }
    // 変更を通知するためのpublicなLiveData
    val selectedTags: LiveData> =
    Transformations.map(_selectedTags) { it.toList() }
    }

    View Slide

  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
    }
    }

    View Slide

  12. Fragment, BottomSheetのコード
    // Fragment, BottomSheet両者で同じインスタンスを取得可能
    viewModel =
    ViewModelProviders.of(targetFragment, object : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun create(modelClass: Class): T =
    FilterViewModel(useCase) as T
    })
    .get(FilterViewModel::class.java)
    viewModel.selectedTags.observe(this, Observer {
    // 通知された選択されたタグでリストをフィルタリング
    adapter.items = filter(it)
    })

    View Slide

  13. 完成︕
    š BottomSheetでタグを選択
    š LiveDataの変更をリスト表⽰するFragmentが監視
    š 選択されたタグでリストをフィルタリング
    š 動的に表⽰切り替え
    フィルタリングの様⼦(GIF)

    View Slide

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

    View Slide

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

    View Slide