androidandroid-support-libraryandroid-appcompatpreference-v7

Inner PreferenceScreen does not open with PreferenceFragmentCompat


My inner PreferenceScreen of PreferenceFragmentCompat is not showing, or seems to ignore tapping events.

I created MyPreferenceFragment that extends PreferenceFragmentCompat

public class MyPreferenceFragment extends PreferenceFragmentCompat {
 @Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    addPreferencesFromResource(R.xml.preferences);
  }
}

then I changed my theme at styles.xml like

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

And finally create my preferences.xml file like

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference android:title="Check Me"/>
    <PreferenceScreen android:title="My Screen"> <!-- This is not opening -->
        <EditTextPreference android:title="Edit text" />
    </PreferenceScreen>
</PreferenceScreen>

At the build.gradle I have added both:

compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:preference-v7:23.0.1'

code of the Activity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

activity_main.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment"
    android:name="com.mando.preferenceapp.MyPreferenceFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Testing the above code I cannot open / get into the preference screen. Am I missing something? Why this isn't working?


Solution

  • After spending many many hours with tries, searching and thankfully with some assistance from the creators of the support library. I've managed to make it work.

    Step 1. Activity

    public class MyActivity extends AppCompatActivity implements
            PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (savedInstanceState == null) {
                // Create the fragment only when the activity is created for the first time.
                // ie. not after orientation changes
                Fragment fragment = getSupportFragmentManager().findFragmentByTag(MyPreferenceFragment.FRAGMENT_TAG);
                if (fragment == null) {
                    fragment = new MyPreferenceFragment();
                }
    
                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.fragment_container, fragment, MyPreferenceFragment.FRAGMENT_TAG);
                ft.commit();
            }
        }
    
        @Override
        public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat,
                                               PreferenceScreen preferenceScreen) {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            MyPreferenceFragment fragment = new MyPreferenceFragment();
            Bundle args = new Bundle();
            args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey());
            fragment.setArguments(args);
            ft.replace(R.id.fragment_container, fragment, preferenceScreen.getKey());
            ft.addToBackStack(preferenceScreen.getKey());
            ft.commit();
            return true;
        }
    }
    

    Tips.

    Step 2. PreferenceFragment

    public class MyPreferenceFragment extends PreferenceFragmentCompat {
    
        public static final String FRAGMENT_TAG = "my_preference_fragment";
    
        public MyPreferenceFragment() {
        }
    
        @Override
        public void onCreatePreferences(Bundle bundle, String rootKey) {
            setPreferencesFromResource(R.xml.preferences, rootKey);
        }
    
    }
    

    Tips.

    The thing that is missing now is the implementation of the back arrow in the actionbar (home action) but this never works by itself ;-)

    I' also created a demo app wrapping all this code you can find it on github.