我正在尝试导航架构组件,现在在设置 Headers 时遇到了困难 . 如何以编程方式设置 Headers 以及它如何工作?
要清除我的问题,让's have an example, where, I' ve设置一个简单的应用程序, MainActivity
托管导航主机控制器, MainFragment
有一个按钮,单击按钮它会转到 DetailFragment
.
堆栈溢出中另一个multiple app bars问题的相同代码 .
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>
所以当启动我的应用程序时, the title is "MainActivity" . 像往常一样,它显示 MainFragment
,其中包含要转到 DetailFragment
的按钮 . 在 DialogFragment
中,我将 Headers 设置为:
getActivity().getSupportActionBar().setTitle("Detail");
First Problem: 因此,单击 MainFragment
上的按钮转到 DetailFragment
,它会转到那里, Headers 会变为"Detail" . 但是点击后退按钮, title changes to "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
, Headers 更改为"Hello" . 但是 second problem ,当我关闭应用程序并重新开始时, Headers 会变回"MainActivity"虽然它应该显示"Hello",但是,知道吗?
好的,然后在 MainFrgment
中添加 setTitle("Hello")
也不起作用 . 例如,活动开始, Headers 为"Hello",转到 DetailsFragment
并再次按后退按钮, Headers 返回"fragment_main" .
唯一的解决方案是在 MainFragment
中同时包含 setTitle("Hello")
和 Navigation.findNavController(view).getCurrentDestination().setLabel("Hello")
.
那么使用导航组件显示片段 Headers 的正确方法是什么?
1 回答
这实际上是因为:
您在xml中设置了哪个 .
setTitle()
此时起作用 . 但是,因为您为那些Fragment
设置了标签,所以在重新创建Activity
时它可能会再次显示标签 . 该解决方案可能会删除android:label
然后使用代码执行您的操作:要么:
在
onCreateView()
.Found a workaround:
然后:
看看这个:Dynamic ActionBar title from a Fragment using AndroidX Navigation