Adding a toolbar to a preferencescreen fragment
Asked Answered
M

3

6

I'm trying to use the Android Jetpack Settings guide with a toolbar. The guide says that the root tag to be <PreferencesScreen>, so I can not include the toolbar in the xml. I'm using a NoActionBar theme. According to the Android Jetpack guide for support app bar variations it is advised to remove the top bar from the activity and instead define it in each destination fragment. So I have the following files:

preferences.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications" />

    <Preference
        app:key="feedback"
        app:summary="Report technical issues or suggest new features"
        app:title="Send feedback" />


</PreferenceScreen>

SettingsFragment.kt

class SettingsFragment: PreferenceFragmentCompat(){
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)
    }
}

Everything runs fine, and the settingsFragments opens well, but because I do use the NoActionBar theme it seems like there is not way for me to add the toolbar without defining it in the main_activity. Is my assessment correct, or is there a way for me to add a custom toolbar afterall to the preference fragment?

Mandamandaean answered 23/11, 2020 at 15:20 Comment(2)
Try a SettingsActivity and inside onCreate replace it with the fragment. That's how I would've done it in java. Not familiar with kt though!Bondwoman
That is the issue, I do not want to make a global toolbar (in the activity). According to their guide it should be possible to implement a toolbar for each fragment. That is why I am posting this question on here. Thanks for your suggestion though.Mandamandaean
A
10

Maybe it's too late but you can achieve it in this way ->

  • define preference theme:
<style name="PrefsTheme" parent="PreferenceThemeOverlay.v14.Material">
    <item name="android:layout">@layout/fragment_settings</item>
</style>
  • fragment_settings.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

<include layout="@layout/item_toolbar" />

<!-- the id is defined by the support lib. -->
<FrameLayout
    android:id="@android:id/list_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:targetApi="n" />

</LinearLayout>
  • set it in your app theme:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="preferenceTheme">@style/PrefsTheme</item>
</style>

Then in your SettingsFragment you can find toolbar by id and make all customizations to it:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    view.findViewById<Toolbar>(R.id.toolbar)?.let {
        // Customize toolbar 
    }
} 
Anna answered 18/5, 2021 at 16:5 Comment(0)
V
3

Other option for this problem. In Preference Screen, u can use Preference Categoy, with layout atribute.

A piece of code that I'm talking about:

<PreferenceCategory
        android:title="Prueba"
        android:textSize="10dp"
        android:layout="@layout/activity_titulo"

        />

Code of activity_titulo:

<?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="wrap_content"
    tools:context=".activities.NuevoParteActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/id_cabecera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.GVenaPDA.AppBarOverlay">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:minHeight="?actionBarSize"
            android:padding="@dimen/appbar_padding"
            android:text="@string/app_name"
            android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title" />

        <TextView
            android:id="@+id/settings_general"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"

            android:padding="5dp"
            android:text="@string/cabecera_info"
            android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Menu"
            />

    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
Vaporescence answered 29/9, 2022 at 9:58 Comment(0)
A
1
class SettingsFragment : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val root = ((listView.parent as FrameLayout).parent as LinearLayout)
    val toolbar = LayoutInflater.from(requireContext())
        .inflate(R.layout.toolbar, root, false) as MaterialToolbar
    toolbar.title = getText(R.string.title_settings)
    root.addView(toolbar, 0)
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    addPreferencesFromResource(R.xml.preferences);
}}

You add a toolbar view dynamically after preferences.xml is inflated. I tried @Yerón Barreiro Martínez's solution. However, I can not reach the toolbar instance on the fragment page. So I can not set the title or click listener.

Also answered 13/8, 2023 at 19:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.