前提・実現したいこと
Android studio(3.5.3)であらかじめ用意されてるButtom Navigatio Activityを使って、画面の切り替えを実現しました。
次にやりたいことは、その子ページ?フラグメント?にあるボタンをタップすると、別の子ページ?フラグメント?にその値を渡すという動作です。
まだまだ初心者で解説を見ても理解できないことが多く、少し困っています。解決方法を知っている方がいましたら、ご教授お願いいたします。
発生している問題
インターネットと書籍を参照していろいろコードを書いてみたんですが、なぜかうまくいきません。
Buttom Navigatio Activityを使用すると各Fragmentに対応したviewModelが設置されていましたが、使わないのではないかと思い、Fragmentクラスの中に入れていません。
該当のソースコード
kotlin
1class MainActivity : AppCompatActivity() { 2 3 override fun onCreate(savedInstanceState: Bundle?) { 4 super.onCreate(savedInstanceState) 5 setContentView(R.layout.activity_main) 6 val navView: BottomNavigationView = findViewById(R.id.nav_view) 7 8 val navController = findNavController(R.id.nav_host_fragment) 9 // Passing each menu ID as a set of Ids because each 10 // menu should be considered as top level destinations. 11 val appBarConfiguration = AppBarConfiguration( 12 setOf( 13 R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications 14 ) 15 ) 16 setupActionBarWithNavController(navController, appBarConfiguration) 17 navView.setupWithNavController(navController) 18 } 19}
kotlin
1class HomeFragment : Fragment() { 2 3 override fun onCreateView( 4 inflater: LayoutInflater, 5 container: ViewGroup?, 6 savedInstanceState: Bundle? 7 ): View? { 8 9 val root = inflater.inflate(R.layout.fragment_home, container, false) 10 return root 11 } 12}
kotlin
1class DashboardFragment : Fragment() { 2 3 override fun onCreateView( 4 inflater: LayoutInflater, 5 container: ViewGroup?, 6 savedInstanceState: Bundle? 7 ): View? { 8 9 val root = inflater.inflate(R.layout.fragment_dashboard, container, false) 10 return root 11 } 12}
kotlin
1class NotificationsFragment : Fragment() { 2 3 override fun onCreateView( 4 inflater: LayoutInflater, 5 container: ViewGroup?, 6 savedInstanceState: Bundle? 7 ): View? { 8 9 val root = inflater.inflate(R.layout.fragment_notifications, container, false) 10 return root 11 } 12}
試したこと
インターネットで漁った文献だと、方法は大まかに4つあるそうです。
1.Bundleを使う
2.ActivityのスコープでViewModelを使う
3.navGraphViewModelsを使う
4.setFragmentResultを使う
そのうちやってみたのは1番と4番です。2番と3番は読んでも理解できませんでしたのでやっていません。
・Bundleを使う
参考文献または書籍を参照してclass HomeFragment : Fragment() { 略 }のonCreateViewメソッドに、ボタンを取得し、そのボタンにリスナーを設定、そのためのリスナークラスを作成し、ボタンタップイベントを以下のように記述しました。その結果実行できませんでした。
kotlin
1private class buttonListener() : View.OnClickListener { 2 override fun onClick(v: View?) { 3 val bundle = Bundle() 4 bundle.putString("string","日本太郎") 5 6 //この行のfragmentManagerが赤文字になります 7 val transaction = fragmentManager?.beginTransaction() 8 9 val homeFragment = HomeFragment() 10 homeFragment.arguments = bundle 11 transaction?.replace(R.id.nav_host_fragment, homeFragment) 12 transaction?.commit() 13 } 14 }
・setFragmentResultを使う。(ViewModelProviderにparentFragmentを渡して、ViewModelを共有する)
kotlin
1class HomeFragment : Fragment() { 2 3 private lateinit var viewModel: HomeViewModel 4 5 override fun onCreateView( 6 inflater: LayoutInflater, 7 container: ViewGroup?, 8 savedInstanceState: Bundle? 9 ): View? { 10 11 val root = inflater.inflate(R.layout.fragment_home, container, false) 12 //この行の「ViewModelProvider」がいけないそうです 13 viewModel = ViewModelProvider(parentFragment).get(DashboardFragment::class.java) 14 15 return root 16 } 17}
補足情報(FW/ツールのバージョンなど)
Android studio 3.5.3
あなたの回答
tips
プレビュー