add action bar with back button in preference activity

11,758

Solution 1

You should do couple of things:

  1. Add the following to your onCreate of PreferenceActivity:

    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
  2. Override onOptionsItemSelected in PreferenceActivity:

    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId())
         {
             case android.R.id.home:
                 NavUtils.navigateUpFromSameTask(this);
                 return true;
         }
         return super.onOptionsItemSelected(item);
     }
    
  3. change the <activity> tag in manifest for your PreferenceActivity to look something like this:

    <activity
      android:name=".PrefsActivity"
      android:label="@string/title_activity_settings"
      android:parentActivityName=".MainActivity">
      <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.android.MainActivity" />
    </activity>
    
  4. Finally put android:launchMode="singleTop" in your MainActivity <activity> tag in manifest:

    <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:launchMode="singleTop"
      android:theme="@style/AppTheme.NoActionBar">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    

Solution 2

The answer Pooya gave won't work for a PreferenceActivity. Instead make your class extend AppCompatActivity, and use a PreferenceFragment to load up the preference. Here is my code for settings:

public class MyPrefsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    }

    @Override
    public boolean onSupportNavigateUp(){
        finish();
        return true;
    }

    public static class MyPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }
    }
}

Put the activity in your AndroidManifest.XML:

<activity android:name=".MyPrefsActivity"
    android:label="Preferences"
    android:theme="@style/AppTheme"/>

And now you can start the settings activity using an intent in my Main Activity (or whichever parent activity you have) as normal:

Intent prefsIntent = new Intent(activity, MyPrefsActivity.class);
activity.startActivity(prefsIntent);

Solution 3

I needed different action bar menu items in my activities so I created my MainActivity with a singleTop launchMode. That was great for getting my child activity's action bar set up, but it left my preferences activity without an action bar.

In the end, the key was in making sure the MainActivity theme had a parent of Theme.AppCompat.Light.NoActionBar:

       <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

and the SettingsActivity theme had the parent Theme.AppCompat.Light.DarkActionBar:

    <activity
        android:name=".SettingsActivity"
        android:label="@string/title_activity_settings"
        android:theme="@style/SettingsTheme"
        android:parentActivityName=".MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="net.deatrich.app.bodyandminddbt.MainActivity" />
    </activity>

In styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>

</style>

<style name="SettingsTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

There's probably a better way to style it but this works.

For anyone else reading, also remember to derive your SettingsActivity from AppCompatPreferenceActivity:

SettingsActivity.java:

public class SettingsActivity extends AppCompatPreferenceActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // I'm displaying a fragment as the main content.
    getFragmentManager().beginTransaction()
            .replace(android.R.id.content, new GeneralPreferenceFragment())
            .commit();

    setupActionBar();

}


private void setupActionBar() {

    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


}

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    int id = item.getItemId();
    if (id == android.R.id.home) {
        if (!super.onMenuItemSelected(featureId, item)) {
            NavUtils.navigateUpFromSameTask(this);
        }
        return true;
    }
    return super.onMenuItemSelected(featureId, item);
}
...
Share:
11,758
user6313452
Author by

user6313452

Updated on July 10, 2022

Comments

  • user6313452
    user6313452 almost 2 years

    Here is my preference activity:

    package com.example.hms.test;
    
    import android.os.Bundle;
    import android.preference.PreferenceActivity;
    
    public class PrefsActivity extends PreferenceActivity {
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.prefs);
        }
    
    }
    

    here I want to show an actionbar with name settings and a back button to home

  • Eslam Sameh Ahmed
    Eslam Sameh Ahmed over 7 years
    But PreferenceActivity does not extend AbbCombatActivity !!
  • Denny
    Denny over 7 years
    Sorry but, getSupportActionBar() is not found when my class extends PreferenceActivity
  • Eido95
    Eido95 almost 7 years
    This approach will not work in case that any kind of NoActionBar theme applied to MyPrefsActivity, so getSupportActionBar() call will return null.
  • Praween k
    Praween k over 5 years
    @Eslam you can manually add "setupActionBar in OnCreate of your preference activity and use like this, private fun setupActionBar() { actionBar?.setDisplayHomeAsUpEnabled(true) } provided you have appBar theme selected in your style.
  • EmmanuelMess
    EmmanuelMess about 5 years
    Sometimes getActionBar().setDisplayShowHomeEnabled(true); getActionBar().setDisplayHomeAsUpEnabled(true); will create a weird space between the back image and the app title. In this case you only need the activity <meta-data ../> in manifest.