androidandroid-preferencesandroid-support-libraryandroid-toolbarpreferencefragment

Toolbar is hidden in nested PreferenceScreen


I use PreferenceFragment in ActionBarActivity from support-v7 library.
In the Activity I have Toolbar. Everything goes okay, until I open a nested PreferenceScreen.
In the opened screen the Toolbar is hidden.

Maybe somebody know a workaround for this issue?

Preferences xml-file:

<?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory android:title="Main category" >

        <EditTextPreference
            android:defaultValue="defaultValue"
            android:key="key_global_setting"
            android:title="Global title" />        

    </PreferenceCategory>

    <PreferenceCategory android:title="Nested screens" >        

        <PreferenceScreen
            android:persistent="false"
            android:title="@string/settings_facility_title" >

        <CheckBoxPreference
            android:defaultValue="false"
            android:key="nested_screen_1_1"
            android:title="Nested screen 1.1 check box" />

        <CheckBoxPreference
            android:defaultValue="true"
            android:key="nested_screen_1_2"
            android:title="Nested screen 1.2 check box" />
        </PreferenceScreen>

        <PreferenceScreen
            android:persistent="false"
            android:title="@string/settings_menu_screen_title" >

         <CheckBoxPreference
            android:defaultValue="true"
            android:key="nested_screen2"
            android:title="Nested screen 2 check box" />
        </PreferenceScreen>        

    </PreferenceCategory>    

</PreferenceScreen> 

Activity layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".SettingsScreen" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar" />

    <FrameLayout
        android:id="@+id/contentSettings"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Solution

  • I found the solution on my own. I used a small work-around of all this nested PreferenceScreen's. I simply made a separation to different xml-preference files, created an additional Fragment which extends PreferenceFragment and there I show an appropriate nested preference screen.
    Maybe somebody would found this useful.

    Github sources link.

    Some code examples below:

    main_preferences.xml

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <PreferenceCategory android:title="Main category" >
    
            <EditTextPreference
                android:defaultValue="defaultValue"
                android:key="key_global_setting"
                android:title="Global title" />
    
        </PreferenceCategory>
    
        <PreferenceCategory android:title="Nested screens" >
    
            <Preference
                android:key="NESTED_KEY1"
                android:persistent="false"
                android:title="Nested screen #1" />
    
            <Preference
                android:key="NESTED_KEY2"
                android:persistent="false"
                android:title="Nested screen #2" />
    
        </PreferenceCategory>
    
    </PreferenceScreen> 
    

    nested_screen1_preferences.xml

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="Nested screen #1" >
    
        <CheckBoxPreference
            android:defaultValue="false"
            android:key="nested_screen_1_1"
            android:title="Nested screen 1.1 check box" />
    
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="nested_screen_1_2"
            android:title="Nested screen 1.2 check box" />
    </PreferenceScreen>
    

    nested_screen2_preferences.xml

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="Nested screen #2">
    
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="nested_screen2"
            android:title="Nested screen 2 check box" />
    </PreferenceScreen>
    

    SettingsActivity.java

    public class SettingsActivity extends ActionBarActivity implements MyPreferenceFragment.Callback {
    
        private static final String TAG_NESTED = "TAG_NESTED";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_settings);
    
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            if (toolbar != null) {
                setSupportActionBar(toolbar);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            }
    
            if (savedInstanceState == null) {
                getFragmentManager().beginTransaction()
                        .add(R.id.contentSettings, new MyPreferenceFragment())
                        .commit();
            }
        }
    
        @Override
        public void onBackPressed() {
            // this if statement is necessary to navigate through nested and main fragments
            if (getFragmentManager().getBackStackEntryCount() == 0) {
                super.onBackPressed();
            } else {
                getFragmentManager().popBackStack();
            }
        }
    
        @Override
        public void onNestedPreferenceSelected(int key) {
            getFragmentManager().beginTransaction().replace(R.id.contentSettings, NestedPreferenceFragment.newInstance(key), TAG_NESTED).addToBackStack(TAG_NESTED).commit();
        }    
    }
    

    MyPreferenceFragment.java

    // The main preference fragment class
    public class MyPreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener {
    
        private Callback mCallback;
    
        private static final String KEY_1 = "NESTED_KEY1";
        private static final String KEY_2 = "NESTED_KEY2";
    
        @Override
        public void onAttach(Activity activity) {
    
            super.onAttach(activity);
    
            if (activity instanceof Callback) {
                mCallback = (Callback) activity;
            } else {
                throw new IllegalStateException("Owner must implement Callback interface");
            }
        }
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.main_preferences);
    
            // add listeners for non-default actions
            Preference preference = findPreference(KEY_1);
            preference.setOnPreferenceClickListener(this);
    
            preference = findPreference(KEY_2);
            preference.setOnPreferenceClickListener(this);
        }
    
        @Override
        public boolean onPreferenceClick(Preference preference) {
            // here you should use the same keys as you used in the xml-file
            if (preference.getKey().equals(KEY_1)) {
                mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_1_KEY);
            }
    
            if (preference.getKey().equals(KEY_2)) {
                mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_2_KEY);
            }
    
            return false;
        }
    
        public interface Callback {
            public void onNestedPreferenceSelected(int key);
        }
    }
    

    NestedPreferencesFragment.java

    public class NestedPreferenceFragment extends PreferenceFragment {
    
        public static final int NESTED_SCREEN_1_KEY = 1;
        public static final int NESTED_SCREEN_2_KEY = 2;
    
        private static final String TAG_KEY = "NESTED_KEY";
    
        public static NestedPreferenceFragment newInstance(int key) {
            NestedPreferenceFragment fragment = new NestedPreferenceFragment();
            // supply arguments to bundle.
            Bundle args = new Bundle();
            args.putInt(TAG_KEY, key);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            checkPreferenceResource();
        }
    
        private void checkPreferenceResource() {
            int key = getArguments().getInt(TAG_KEY);
            // Load the preferences from an XML resource
            switch (key) {
                case NESTED_SCREEN_1_KEY:
                    addPreferencesFromResource(R.xml.nested_screen1_preferences);
                    break;
    
                case NESTED_SCREEN_2_KEY:
                    addPreferencesFromResource(R.xml.nested_screen2_preferences);
                    break;
    
                default:
                    break;
            }
        }
    
    }