Search code examples
androidandroid-preferences

AppCompatPreferenceActivity with addPreferencesFromResource up not working


I am using AppCompatPreferenceActivity so that I can add the Toolbar at the top of the screen. Problem is that the back button on the toolbar is not working. Since I am not using my own layout I have no access to the Toolbar in order to set setNavigationOnClickListener as suggested here

This is my Activity:

public class SettingsActivity extends AppCompatPreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // Load the preferences from an XML resource
    super.onCreate(savedInstanceState);

        getSupportActionBar().setTitle(R.string.preferences);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesMain()).commit();
}

/**
 * This fragment contains a second-level set of preference that you
 * can get to by tapping an item in the first preferences fragment.
 */
public static class PreferencesMain extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);


        ((Preference)findPreference(getString(R.string.settings_account_about))).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(getActivity(), "About clicked", Toast.LENGTH_LONG).show();
                return true;
            }
        });

        ((Preference)findPreference(getString(R.string.settings_account_logout))).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                new UserSignOutRequest(getActivity(),
                    new ServerSuccessListener<CreateUserEntity>() {
                        @Override
                        public void onSuccessResponse(String response, CreateUserEntity jsonResponse) {
                            UserControl.signOut(getActivity());
                            Utilities.startSignInActivity(getActivity());
                        }

                    },
                    new ServerErrorListener() {
                        @Override
                        public void onErrorResponse(ServerRequestError serverRequestError) {

                        }
                        }
                ).execute(getActivity());
                return true;
            }
        });

        ((Preference)findPreference(getString(R.string.settings_account_deleteAccount))).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(getActivity(), "Delete Account clicked", Toast.LENGTH_LONG).show();
                return true;
            }
        });
    }

@Override
protected boolean isValidFragment (String fragmentName) {
    return true;
}



@Override
public void onBackPressed() {
    finish();   // If on first fragment then exit then activity
}

}

and this is my XML file:

    <!-- This PreferenceScreen tag sends the user to a new fragment of
         preferences.  If running in a large screen, they can be embedded
         inside of the overall preferences UI. -->
    <PreferenceScreen
        android:title="@string/settings_notifications_managePushTitle"
        android:summary="@string/settings_notifications_managePushSummary"
        android:background="@android:color/black">


            <PreferenceCategory
                android:title="@string/settings_notifications_managePushHeader">

                <CheckBoxPreference
                    android:key="checkbox_preference"
                    android:title="@string/settings_notifications_managePushEntry1Title"
                    android:summary="@string/settings_notifications_managePushEntry1Summary" />
            </PreferenceCategory>

    </PreferenceScreen>

    <PreferenceScreen
        android:title="@string/settings_notifications_manageEmailTitle"
        android:summary="@string/settings_notifications_manageEmailSummary"
        android:background="@android:color/black">
            <PreferenceCategory
                android:title="@string/settings_notifications_manageEmailHeader">

                <CheckBoxPreference
                    android:key="checkbox_preference"
                    android:title="@string/settings_notifications_managePushEntry1Title"
                    android:summary="@string/settings_notifications_managePushEntry1Summary" />
            </PreferenceCategory>

    </PreferenceScreen>

    <PreferenceScreen
        android:title="@string/settings_notifications_manageSMSTitle"
        android:summary="@string/settings_notifications_manageSMSSummary"
        android:background="@android:color/black">

        <PreferenceCategory
            android:title="@string/settings_notifications_manageSMSHeader">

            <CheckBoxPreference
                android:key="checkbox_preference"
                android:title="@string/settings_notifications_managePushEntry1Title"
                android:summary="@string/settings_notifications_managePushEntry1Summary" />
        </PreferenceCategory>

    </PreferenceScreen>


</PreferenceCategory>

<PreferenceCategory
    android:title="@string/settings_moneyAndCredits"
    android:layout="@layout/preference_category">

    <!-- The key value is unused but is required so that findPreference can work -->
    <customviews.IconPreference android:title="@string/settings_moneyAndCredits_defaultPaymentMethod"
        android:key="@string/settings_moneyAndCredits_defaultPaymentMethod"
        app:preferenceIcon="@drawable/settings_payment_method"/>
    <customviews.IconPreference android:title="@string/settings_moneyAndCredits_incomingPaymentAccounts"
        android:key="@string/settings_moneyAndCredits_incomingPaymentAccounts"
        app:preferenceIcon="@drawable/settings_manage_incomings"/>


</PreferenceCategory>


<PreferenceCategory
    android:title="@string/settings_account"
    android:layout="@layout/preference_category">
    <!-- The key value is unused but is required so that findPreference can work -->
    <customviews.IconPreference android:title="@string/settings_account_about"
        android:key="@string/settings_account_about"
        app:preferenceIcon="@drawable/settings_about"/>
    <customviews.IconPreference android:title="@string/settings_account_logout"
        android:key="@string/settings_account_logout"
        app:preferenceIcon="@drawable/settings_logout"/>
    <customviews.IconPreference  android:title="@string/settings_account_deleteAccount"
        android:key="@string/settings_account_deleteAccount"
        app:preferenceIcon="@drawable/settings_delete_user"/>

</PreferenceCategory>

I am using two levels of PreferenceScreen because I need to mix different types and any other way gave me overlayed screens.


Solution

  • I think you have access to ActionBar in both the cases i.e. default layout and custom layout (as far as getSupportActionBar() is returning you the ActionBar). And you already have enabled back button by adding getSupportActionBar().setDisplayShowHomeEnabled(true); you can just override onOptionsItemSelected in your Activity like this

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            // Write your code here
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

    Or if you want to add this method in Fragment just add setHasOptionsMenu(true); in Fragment's onCreate method and override onOptionsItemSelected in your Fragment. I think it is what you want. Isn't that?