ActionBar in PreferenceActivity
Asked Answered
D

8

12

Example: Android Market

In my application I am using the new Action Bar Compatibility sample from Google (located at <sdk>/samples/android-<version>/ActionBarCompat) which works great. The only problem I have is applying this to my PreferenceActivity in order to get a screen like the settings in the Android Market (see picture).

To fill the ActionBar with icons, each Activity must extend the ActionBarActivity class. The problem is that my Activity already extends PreferenceActivity and in Java classes can not extend more than one class.

There must be a way to get the ActionBar together with a PreferenceScreen. I would be glad if anybody could provide a solution for this common issue.

P.S.: A solution like in How to add a button to PreferenceScreen does not fit because the ActionBar is actually the title bar and so this is more a Java than a layout thing.

Despot answered 28/10, 2011 at 11:55 Comment(4)
See this thread, I think it will help you: #2697733 [1]: #2697733Pollination
With a lot of hacking and reflection, a skilled programmer could do it. I tried - I failed.Congratulant
I got the official PreferenceFragment working!Congratulant
If you wish , you can try out a library I've made: github.com/AndroidDeveloperLB/MaterialStuffLibraryPhilan
S
15

Edit: My answer below is rather hacky and it seems like it is now outdated (for pre Android 3.0) Have a look at the other answers for less hacky and more current solutions ~pyko 2014-09-01


I managed to get it working - not sure if this is the nicest/cleanest solution, but it works.

Had to make the following changes:

  1. Make a copy of ActionBarActivity and have the new class extend PreferenceActivity

    public abstract class ActionBarPreferenceActivity extends PreferenceActivity {
        // contents exactly the same as 'ActionBarActivity'
    }
    
  2. Modify onCreate() in ActionBarHelperBase.java slightly - make a special case for PreferenceActivity classes

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // If the activity is a PreferenceActivity, don't make the request
        if (!(mActivity instanceof PreferenceActivity)) {
            mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        }
    
  3. Have your PreferenceActivity extend this class and add request for FEATURE_CUSTOM_TITLE before you call super.onCreate()

    public class MyPreferenceActivity extends ActionBarPreferenceActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // add this line
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
            // etc etc
        }
    
        // etc etc
    }
    

As far as I can tell, changes 2 and 3 are needed because for PreferenceActivity:

"As soon as you call super.onCreate(), the ViewGroup will be set up and so, you are not allowed to change the Window's parameters." (see Oliver's comment to the answer)

I guess the order of how components in PreferenceActivity activities are created is different to plain Activity activities .

Strife answered 24/12, 2011 at 11:6 Comment(5)
Thank you for working this out. It seems like there is no clean solution for this. I now use ActionBarSherlock for Action bar implementations which provides much more functionality than the Android compatibility action bar.Despot
In order to get this working I had to check if the android api version was below 3.0 (= 11) otherwise this didn't work. So in the preference class I have to do this before the super.onCreate(...): if (ContextUtils.getAndroidApiVersion() < OSContants.API.HONEYCOMB_3_0) { requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // For compatibility with the action-bar }Absinthism
Setting up a normal actionbaractivity that simply loads in a PreferenceFragment accomplishes this. In case anyone else gets here but didn't consider this simple solution.Tattered
When you say "Make a copy of ActionBarActivity" do you mean to take the source code and copy it into my own project ? For example, from here? android.googlesource.com/platform/frameworks/support/+/…Zincography
Maybe this worked once upon a time, but with appcompat-v7_19.1.0 ActionBarActivity#onCreate calls ActionBarActivityDelegate.createDelegate((ActionBarActivity) this). Which means that you cannot pass in a PreferenceActivity subclass.Battledore
A
5

If you want to try a PreferenceFragment implementation based on support-v4 Fragment:

https://github.com/kolavar/android-support-v4-preferencefragment

I´m using it by myself and it isnt much work turning PreferenceActivity into PreferenceFragment.

Adolphus answered 23/10, 2013 at 9:29 Comment(0)
A
1

Can you just clone the code for ActionBarActivity, and change "extends Activity" to "extends PreferenceActivity"? Then extend your new class instead of ActionBarActivity.

From all the Google apps I've seen, though, it seems unusual to put buttons in the action bar of a PreferenceActivity. If you're not putting buttons on it, you could just use a values-v11 alternate style resource to show the holo theme, and set that style in the manifest for your PreferenceActivity.

Alarick answered 5/11, 2011 at 21:27 Comment(1)
No because of the ActionBarActivityDelegateCongratulant
P
1

I used in my application this actionbar https://github.com/johannilsson/android-actionbar and it's work great with this thread How to add a button to PreferenceScreen

Pollination answered 21/12, 2011 at 8:51 Comment(1)
Thanks. I now use ActionBarSherlock which is very nice. The first versions of this library used johannilsson's Actionbar as the basis.Despot
R
1

I'd like to thank to @pyko providing a great answer, but it has problem that it won't work well on HoneyComb and above. well you can have a hack way to get it around like @AndroidDev said; But @pyko is gonna pollute the ActionBarHelperBase class, and @AndroidDev isn't very transparent.The best way is to create ActionBarActivityPreferences who extends from PreferenceActivity; and in onCreate method, change the order of calling parent method:

@Override
protected void onCreate(Bundle savedInstanceState) {
    //IMPORTATNT: MAKE SURE actionBarHelper called before super;
    //as super oncreate of prefenceactivity is actuallying setting the content view
    mActionBarHelper.onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
}

why calls 'mActionBarHelper.onCreate(savedInstanceState);' before 'super.onCreate(savedInstanceState);' , that is because super (i.e. PreferenceActivity) is actually setting the content view in its onCreate method, which would cause crash ("requestFeature() must be called before adding content'). SO what you need do is to swap the order, make sure ' mActionBarHelper.onCreate(savedInstanceState);' is called before super. In this way, we don't need to pollute the 'ActionBarHelperBase' yet we keep SettingActivity very clean because we encapsulate the tricky detail to 'ActionBarActivityPreferences' and bang!

Rosaline answered 19/7, 2012 at 6:30 Comment(0)
B
1

You can easily add action bar in preference activity by the following changes:

In AndroidManifest.xml :

<activity
        android:name=".activity.SettingsActivity"
        android:theme="@style/SettingsTheme"
        android:label="Settings"/>

In v21/styles.xml

<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
    <item name="android:colorPrimary">@color/colorPrimary</item>
    <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
</style>

In v14/styles.xml for Back API support:

<style name="SettingsTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBar.V14.Movie.NoTitle</item>
</style>
Bedell answered 16/12, 2016 at 18:19 Comment(0)
S
0

Thanks, just an update, you need to add an if statement before the Custom Title line to support HoneyComb and above.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
   requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
Steelman answered 9/4, 2012 at 17:17 Comment(0)
C
0

You can get a ActionBarSherlock lib and let you code extends SherlockPreference;

Cutler answered 24/4, 2015 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.