新しい Navigation from Android Jetpack。
ルートアクティビティのセットアップは非常に簡単です。
_override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
val navController = findNavController(R.id.navigationFragment)
setupActionBarWithNavController(navController)
bottomNavigationView.setupWithNavController(navController)
}
_
ナビゲーショングラフでフラグメントのタイトルが定義されている場合、うまく機能します。しかし、1つのフラグメントについて、タイトルを動的に設定したいと思います。
findNavController().currentDestination.label = "Hello world"
で試しましたが、何もしません。
もちろん_(activity as? AppCompatActivity)?.supportActionBar?.title = "Hello world"
_のようなトリックを使用することもできますが、setupActionBarWithNavController()
が私のために行う魔法を壊すと感じています。アクションバーのタイトルを動的に更新する方法はありますか?
1.0.0-alpha08
、ナビゲーションビットがナビゲーションアクションの引数である場合、NavigationUIビットでタイトルを動的に設定できます。
そのため、たとえば、ナビゲーショングラフには次のようなものがあります。
<fragment
Android:id="@+id/displayFragment"
Android:name="com.commonsware.jetpack.sampler.nav.DisplayFragment"
Android:label="Title: {title}" >
<argument
Android:name="modelId"
app:argType="string" />
<argument
Android:name="title"
app:argType="string" />
</fragment>
ここでは、Android:label
属性の<fragment>
には引数名が中括弧({title}
in "Title: {title}"
。アプリバーのタイトルは、ラベルの値に設定され、{title}
は、title
引数の値に置き換えられます。
それよりも複雑なものが必要な場合(たとえば、IDでモデルを検索し、そこからプロパティを読み取る場合)、この質問に対する他の回答で概説されているような、より多くの手動アプローチを使用する必要があります。
現在のところ、Jetpack Navigation Architectureコンポーネントは、これを行うための「組み込み」方法を提供していません。そのためには、独自の「カスタム」メソッドを実装する必要があります。
新しいJetpack Navigation Architectureコンポーネントに追加された宛先の動的ラベルの機能を取得するための既存の機能要求があります。この機能が必要/必要なためにここにいる場合は、既存の機能リクエストにスターを付けてください: https://issuetracker.google.com/issues/80267266
ホストアクティビティがMainActivity
であることを考慮して、次のコードをMainActivity
のonCreate
funに追加するだけです。
val navController = Navigation.findNavController(this, R.id.nav_Host_fragment)
// setting title according to fragment
navController.addOnDestinationChangedListener {
controller, destination, arguments ->
toolbar.title = navController.currentDestination?.label
}
さて、ナビゲーションUIはこの機能をサポートしています。これで、ActionBar
タイトルが動的に変更されます。 ActionBar
でNavController
をセットアップする必要があります。
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
preferedTheme()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
navController = findNavController(R.id.nav_controller_fragment)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
}
そして、ナビゲーショングラフにアクションバーのラベルを設定します:
<navigation xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/mobile_navigation"
app:startDestination="@id/mainFragment">
<fragment Android:id="@+id/mainFragment"
Android:name="com.cinderellaman.general.ui.fragments.MainFragment"
Android:label="General"
tools:layout="@layout/main_fragment"/>
そして現在、Navigate Upもサポートしています。
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
graph.xmlファイルからラベルを削除
Android:label="fragment_info"
フラグメント自体からフラグメントのタイトルを動的に設定する場合は、オールドスクールのアプローチを使用します
getActivity().setTitle("Your Title");
別の解決策は、ViewModelとLiveDataを使用して、viewmodelをアクティビティとフラグメントに接続し、viewmodel内にlivedataフィールドを追加することです。
val title = MutableLiveData<String>()
アクティビティからこのフィールドを観察し、変更されている場合はツールバーのタイトルを更新します
viewModel?.title?.observe(this, Observer {
my_toolbar.title=it
})
目的のフラグメントから、ビューモデル内のタイトルフィールドを変更します
viewModel?.title?.value="New title"
issue が修正されるまで、単純なリスナーが動作します:
/**
* Temporary solution to dynamically change title of actionbar controlled by Navigation component
* Should be removed as soon as the bug on Navigation will be fixed: (https://issuetracker.google.com/issues/80267266)
*/
interface TempToolbarTitleListener {
fun updateTitle(title: String)
}
class MainActivity : AppCompatActivity(), TempToolbarTitleListener {
...
override fun updateTitle(title: String) {
binding.toolbar.title = title
}
}
フラグメントからタイトルを変更:
(activity as TempToolbarTitleListener).updateTitle("custom title")
アクティビティのタイトルを試すと、フラグメントのタイトルがオーバーライドされるようです。安全のため、onResume
を付ける必要があります。
override fun onResume() {
super.onResume()
activity?.toolbar.title = "YOUR_TITLE_HERE"
}
わたしにはできる !
注:アクティビティにツールバーウィジェットが必要です
アクティビティのxmlにこのようなツールバーを追加します
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"">
<com.google.Android.material.appbar.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
</com.google.Android.material.appbar.AppBarLayout>
<!-- Other Widgets -->
</androidx.coordinatorlayout.widget.CoordinatorLayout>