Android:使用Jetpack组件时如何为Preferences添加Toolbar?
嘿,我正好遇到过一模一样的问题,给你几个亲测有效的解决方案,你可以根据自己的项目情况来选:
方案一:给设置页面套个带Toolbar的容器Fragment
这个方案最直观,通过一个普通Fragment作为容器,把PreferenceFragmentCompat嵌套进去,同时在容器里添加自定义Toolbar:
- 先创建容器布局
fragment_settings_container.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/settings_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" /> <FrameLayout android:id="@+id/settings_fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
- 创建容器Fragment
SettingsContainerFragment:
class SettingsContainerFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_settings_container, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 配置自定义Toolbar val toolbar = view.findViewById<Toolbar>(R.id.settings_toolbar) (activity as AppCompatActivity).setSupportActionBar(toolbar) (activity as AppCompatActivity).supportActionBar?.apply { setDisplayHomeAsUpEnabled(true) title = getString(R.string.settings_title) } // 嵌套加载PreferenceFragmentCompat childFragmentManager.beginTransaction() .replace(R.id.settings_fragment_container, SettingsFragment()) .commit() // 处理返回按钮逻辑 toolbar.setNavigationOnClickListener { findNavController().popBackStack() } } }
- 最后把
nav_graph.xml里原来的SettingsFragment替换成这个容器Fragment,跳转时导航到容器Fragment即可。
方案二:直接在PreferenceFragmentCompat里自定义布局
不想加额外容器的话,可以直接重写PreferenceFragmentCompat的onCreateView方法,把Toolbar嵌入进去:
- 创建带Toolbar的布局
fragment_settings_with_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/settings_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" /> <FrameLayout android:id="@+id/preference_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
- 修改你的
SettingsFragment:
class SettingsFragment : PreferenceFragmentCompat() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 先加载自定义布局 val rootView = inflater.inflate(R.layout.fragment_settings_with_toolbar, container, false) val preferenceContainer = rootView.findViewById<FrameLayout>(R.id.preference_container) // 让Preference的内容加载到容器里 val preferenceView = super.onCreateView(inflater, preferenceContainer, savedInstanceState) preferenceContainer.addView(preferenceView) // 配置Toolbar val toolbar = rootView.findViewById<Toolbar>(R.id.settings_toolbar) (activity as AppCompatActivity).setSupportActionBar(toolbar) (activity as AppCompatActivity).supportActionBar?.apply { setDisplayHomeAsUpEnabled(true) title = getString(R.string.settings_title) } toolbar.setNavigationOnClickListener { findNavController().popBackStack() } return rootView } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences, rootKey) } }
方案三:在MainActivity中动态控制Toolbar
如果你的MainActivity本身已经有Toolbar,只是在设置页需要切换Toolbar的行为,可以通过导航监听来动态配置:
class MainActivity : AppCompatActivity() { private lateinit var navController: NavController private lateinit var drawerLayout: DrawerLayout private lateinit var toolbar: Toolbar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) toolbar = findViewById(R.id.main_toolbar) setSupportActionBar(toolbar) drawerLayout = findViewById(R.id.drawer_layout) navController = findNavController(R.id.nav_host_fragment) // 监听页面导航变化 navController.addOnDestinationChangedListener { _, destination, _ -> when (destination.id) { R.id.settingsFragment -> { // 设置页显示返回按钮,修改标题 supportActionBar?.apply { setDisplayHomeAsUpEnabled(true) title = getString(R.string.settings_title) } // 锁定抽屉,防止侧滑 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) } else -> { // 其他页面恢复抽屉菜单和默认标题 supportActionBar?.apply { setDisplayHomeAsUpEnabled(false) title = getString(R.string.app_name) } drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) } } } } override fun onSupportNavigateUp(): Boolean { // 设置页点击返回按钮时回退,其他页面处理抽屉导航 return if (navController.currentDestination?.id == R.id.settingsFragment) { navController.popBackStack() true } else { NavigationUI.navigateUp(navController, drawerLayout) } } }
内容的提问来源于stack exchange,提问作者dev.farmer
相关产品推荐
相关产品推荐

