ナビゲーションアーキテクチャコンポーネントを試してみましたが、タイトルの設定が困難になりました。プログラムでタイトルを設定するにはどうすればよいですか?
私の質問を明確にするために、ナビゲーションホストコントローラーをホストしているMainActivity
を使用してシンプルなアプリをセットアップした例を見てみましょう。MainFragment
にはボタンがあり、ボタンをクリックするとボタンが表示されますDetailFragment
に。
スタックオーバーフローに関する 複数のアプリバー の別の質問からの同じコード。
MainActivity
_public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Setting up a back button
NavController navController = Navigation.findNavController(this, R.id.nav_Host);
NavigationUI.setupActionBarWithNavController(this, navController);
}
@Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.nav_Host).navigateUp();
}
}
_
MainFragment
_public class MainFragment extends Fragment {
public MainFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button buttonOne = view.findViewById(R.id.button_one);
buttonOne.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.detailFragment));
}
}
_
DetailFragment
_public class DetailFragment extends Fragment {
public DetailFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail, container, false);
}
}
_
activity_main.xml
_<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
Android:layout_height="match_parent"
Android:animateLayoutChanges="true"
tools:context=".MainActivity">
<com.google.Android.material.appbar.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:animateLayoutChanges="true"
Android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.Android.material.appbar.AppBarLayout>
<fragment
Android:id="@+id/nav_Host"
Android:name="androidx.navigation.fragment.NavHostFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="top"
Android:layout_marginTop="?android:attr/actionBarSize"
app:defaultNavHost="true"
app:layout_anchor="@id/bottom_appbar"
app:layout_anchorGravity="top"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:navGraph="@navigation/mobile_navigation" />
<com.google.Android.material.bottomappbar.BottomAppBar
Android:id="@+id/bottom_appbar"
Android:layout_width="match_parent"
Android:layout_height="?android:attr/actionBarSize"
Android:layout_gravity="bottom" />
<com.google.Android.material.floatingactionbutton.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:layout_anchor="@id/bottom_appbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
_
navigation.xml
_<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.example.MainFragment"
Android:label="fragment_main"
tools:layout="@layout/fragment_main" >
<action
Android:id="@+id/toAccountFragment"
app:destination="@id/detailFragment" />
</fragment>
<fragment
Android:id="@+id/detailFragment"
Android:name="com.example.DetailFragment"
Android:label="fragment_account"
tools:layout="@layout/fragment_detail" />
</navigation>
_
したがって、私のアプリを起動すると、タイトルは「MainActivity」になります。いつものように、MainFragment
に移動するためのボタンを含むDetailFragment
が表示されます。 DialogFragment
で、タイトルを次のように設定しました。
_getActivity().getSupportActionBar().setTitle("Detail");
_
最初の問題:MainFragment
のボタンをクリックしてDetailFragment
に移動すると、そこに移動してタイトルが変更されます詳細へ"。しかし、[戻る]ボタンをクリックすると、タイトルが "fragment_main"に変わります。そこで、次のコード行をMainFragment
に追加しました。
_@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// ...
//Showing the title
Navigation.findNavController(view)
.getCurrentDestination().setLabel("Hello");
}
_
DetailFragment
からMainFragment
に戻ると、タイトルが「Hello」に変わります。しかし、ここで2番目の問題が発生します。アプリを閉じて再起動すると、タイトルが「MainActivity」に戻りますが、「Hello」と表示されているはずです代わりに、知っていますか?
では、MainFrgment
にsetTitle("Hello")
を追加しても機能しません。たとえば、アクティビティが開始され、タイトルが「Hello」の場合、DetailsFragment
に移動して戻るボタンをもう一度押すと、タイトルが「fragment_main」に戻ります。
唯一の解決策は、MainFragment
にsetTitle("Hello")
とNavigation.findNavController(view).getCurrentDestination().setLabel("Hello")
の両方を含めることです。
では、ナビゲーションコンポーネントを使用してフラグメントのタイトルを表示する適切な方法は何ですか?
それは実際には次の理由による:
_Android:label="fragment_main"
_
Xmlで設定したもの。
では、ナビゲーションコンポーネントを使用して
Fragment
sのタイトルを表示する適切な方法は何ですか?
setTitle()
はこの時点で機能します。ただし、これらのFragment
sにラベルを設定したため、Activity
を再作成するときにラベルが再度表示される場合があります。解決策はおそらく_Android:label
_を削除してからコードであなたのことをするでしょう:
_getActivity().getSupportActionBar().setTitle("yourtitle");
_
または:
_((AppCompatActivity) getActivity()).getSupportActionBar().setSubtitle();
_
onCreateView()
内。
回避策が見つかりました:
_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")
_
これもチェックしてください: AndroidXナビゲーションを使用したフラグメントの動的ActionBarタイトル
アプリバーを指定しない場合は、このコードをフラグメントで使用できます(デフォルトのアプリバー)。
(activity as MainActivity).supportActionBar?.title = "Your Custom Title"
ナビゲーショングラフのAndroid:label
属性を忘れずに削除してください
ハッピーコード^-^
各画面にAppBarを含めることをお勧めします。コードの重複を回避するには、タイトルをパラメーターとして、AppBarを構築するヘルパーを作成します。次に、各画面クラスでヘルパーを呼び出します。
別のアプローチはこれである可能性があります:
fun Fragment.setToolbarTitle(title: String) {
(activity as NavigationDrawerActivity).supportActionBar?.title = title
}
ナビゲーショングラフのxmlファイルを使用して、フラグメントのラベルを引数に設定できます。次に、親フラグメントで、SafeArgsを使用して引数を渡し、デフォルト値を指定して、タイトルがnullまたは空にならないようにします。
<!--set the fragment's title to characters name passed as an argument-->
<fragment
Android:id="@+id/characterDetailFragment2"
Android:name="ui.character.CharacterDetailFragment"
Android:label="{character_name}"
tools:layout="@layout/fragment_character_detail">
<argument
Android:name="character_name"
Android:defaultValue="Name"
app:argType="string" />
</fragment>