質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

3682閲覧

Android Kotlin 異なるフラグメント間でのViewModelデータ共有

falcom_zx

総合スコア65

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2020/05/17 11:35

一つの画面に異なるフラグメント(MainFragmentとSubFragment)を配置し、ViewModelでデータ共有しています。
MainFragmentのButtonをタップしたら、MainFragmentおよびSubFragmentそれぞれに配置したTextViewの中身を同時に同じ値にしたいと思ってます。
以下の通りコーディングしたところ、MainFragmentのTextViewしかカウントアップしません。SubFragmentのTextViewも同時にカウントアップさせたいのですが、どの様に直せば良いでしょうか?
イメージ説明

Kotlin

1//MainFragment.kt 2class MainFragment :Fragment() { 3 4 private lateinit var viewModel: DataViewModel 5 private lateinit var binding: FragmentMainBinding 6 7 override fun onCreateView( 8 inflater: LayoutInflater, 9 container: ViewGroup?, 10 savedInstanceState: Bundle? 11 ): View? { 12 binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false) 13 viewModel = ViewModelProviders.of(this).get(DataViewModel::class.java) 14 binding.dataViewModel = viewModel 15 binding.lifecycleOwner = viewLifecycleOwner 16 17 return binding.root 18 } 19}

Kotlin

1//SubFragment.kt 2class SubFragment: Fragment() { 3 4 private lateinit var viewModel: DataViewModel 5 private lateinit var binding: FragmentSubBinding 6 7 override fun onCreateView( 8 inflater: LayoutInflater, 9 container: ViewGroup?, 10 savedInstanceState: Bundle? 11 ): View? { 12 binding = DataBindingUtil.inflate(inflater, R.layout.fragment_sub, container, false) 13 viewModel = ViewModelProviders.of(this).get(DataViewModel::class.java) 14 binding.dataViewModel = viewModel 15 binding.lifecycleOwner = viewLifecycleOwner 16 17 return binding.root 18 } 19 20}

Kotlin

1//DataViewModel.kt 2class DataViewModel: ViewModel() { 3 4 private var _variable = MutableLiveData<Int>() 5 val variable: LiveData<Int> = _variable 6 7 init { 8 _variable.value = 1 9 } 10 11 fun count() { 12 _variable.value = (_variable.value)!!.plus(1) 13 } 14}

XML

1//fragment_main.xml 2<layout 3 ...> 4 5 <data> 6 <variable 7 name="dataViewModel" 8 type="com.example.trial_mvvm.DataViewModel" /> 9 </data> 10 11 <androidx.constraintlayout.widget.ConstraintLayout 12 ...> 13 <Button 14 ... 15 android:onClick="@{() -> dataViewModel.count()}" 16 .../> 17 18 <TextView 19 ... 20 android:text="@{String.valueOf(dataViewModel.variable)}" 21 .../> 22 </androidx.constraintlayout.widget.ConstraintLayout> 23</layout>

XML

1//fragment_sub.xml 2<layout 3 ...> 4 5 <data> 6 <variable 7 name="dataViewModel" 8 type="com.example.trial_mvvm.DataViewModel" /> 9 </data> 10 11 <androidx.constraintlayout.widget.ConstraintLayout 12 ...> 13 14 <TextView 15 ... 16 android:text="@{String.valueOf(dataViewModel.variable)}" 17 .../> 18 </androidx.constraintlayout.widget.ConstraintLayout> 19</layout>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

アプリのビジネスロジックに関するデータを共有したいのであればModel側にデータを持たせるのがベストな方法ですが、あくまで画面に関するデータをFragment間で共有したいということであれば、Activity向けに生成したViewModelを経由させるのがGoogleが推奨している方法です。ドキュメント

ViewModel生成のコードを、以下のように変更してみてください。こうするだけで、各FragmentやActivityのライフサイクルを気にすることなく画面上のデータを共有することができます。

kotlin

1ViewModelProviders.of(requireActivity()).get(DataViewModel::class.java)

もしくは、fragment-ktxを導入して、以下のようにシンプルにメンバとして定義できます。

kotlin

1private val viewModel: DataViewModel by activityViewModels()

投稿2020/05/17 16:19

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

falcom_zx

2020/05/18 11:38

イメージ通りに動かすことが出来ました。ViewModelProviders.ofはlifecycleライブラリ2.2.0から非推奨になっていたのですね。fragment-ktxを導入して対応することにしました。このたびは親切な回答ありがとうございました。
guest

0

ViewModelでデータ共有しています

していないということではないでしょうか.
ViewModelProviders.of の引数が何を意味するのかをよくお調べになっては如何でしょうか.

投稿2020/05/17 16:26

jimbe

総合スコア12545

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

falcom_zx

2020/05/18 11:07

ヒントありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問