Alternatives to PreferenceFragment with android-support-v4
Asked Answered
H

9

90

I've come to a sudden halt in the development of my app as I realized that PreferenceFragments weren't supported in this library. Are there any alternatives that a rookie android developer can use to overcome this obstacle ?

This is my main window as of right now

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
<TabHost
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

                <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            />

</TabHost>
</LinearLayout>

For my TabActivity I'm using something I found online. Here's a snippet:

public class TabControlActivity extends FragmentActivity implements TabHost.OnTabChangeListener 
{
public static final int INSERT_ID = Menu.FIRST;
public static TabControlActivity thisCtx;
private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;

private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory 
{

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

...*snip*...

Is there any to implement something that resembles a preferencefragment(or preferenceActivity) using the android-support-v4 compatibility library ?

Hereunder answered 20/3, 2012 at 8:17 Comment(3)
possible duplicate of Was PreferenceFragment intentionally excluded from the compatibility package?Elegant
Not really a duplicate as I am in a situation where I "need" these preferences to be shown within a tabhost. See my editHereunder
See my updated answer. PreferenceFragmentCompat was recently added to the support library.Semiweekly
M
86

UPDATE - 6/11/2015

Support-v7 library now includes PreferenceFragmentCompat. So it will be a better idea to use it.


Add the following project as a library project to your application.

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

You can keep everything including your fragment transaction as it is. When importing the PreferenceFragment class, make sure the correct import header is user.

import android.support.v4.preference.PreferenceFragment;

instead of

import android.preference.PreferenceFragment;
Mercurate answered 22/12, 2013 at 8:15 Comment(9)
This worked great so far. Thanks for the info! Please make the link to github.com/kolavar/android-support-v4-preferencefragment more visible. Difficult to find the actual link. I'm on Chrome.Brockington
That github code seems to have serious issues... I cannot use RingtonePreference and also OnSharedPreferenceChangeListener does not seem to get any changes!Mongeau
I was thinking that it's a good idea to use this library. But i realized that it's not as good as i thought. Trying to override onPrepareOptionMenu method shows me a strange signature (returns void) different to the default one we all know (returns boolean) !!! a serious issue.Chromatism
upvoted, and you are entitled to a free dinner whenever you come to Madrid ... this issue was driving me crazy!Capitally
@mansoulx onPrepareOptionsMenu always has a void return type on fragments (unlike for Activities, for which it is boolean), so this signature is entirely as expected.Powe
getting this exeption while opening an alert dialog. I would before stick with the PrefernceActivity instead. android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application at android.view.ViewRootImpl.setView(ViewRootImpl.java:589) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)Clingy
Issues with the library should probably be reported on the github project.Midbrain
If anyone's like me, this is the dependency they are looking for: compile 'com.android.support:preference-v7:23.4.0'Koslo
1. Information on current versions of support libraries (to be used for Gradle builds), including v4 and v7 Preference Support Libraries is here: developer.android.com/topic/libraries/support-library/… 2. There is no support for RingtonePreference. For a workaround see: code.google.com/p/android/issues/detail?id=183255 After spending a couple of hours converting my code to use PreferenceFragmentCompat I returned back to android.preference.PreferenceFragment, because there is no support for preference headers (shown in their own fragment...)Concavoconvex
R
128

I know this is an old question, but you can now use PreferenceFragmentCompat from com.android.support:preference-v7:23.3.0

Romelda answered 1/9, 2015 at 9:37 Comment(4)
For me it works only with com.android.support:preference-v7:23.0.1.Bacteriology
This doesn't seem to be on the dependency servers when trying to add it from Android Studio. DO I need to add a repository for it?Countrybred
It doesn't contain that classRarotonga
I accidentally upvoted this answer and I can't undo it now, so instead I'll just note that PreferenceFragmentCompat has some major issues: see this and this bug report, for example, and many more here. I ended up using the deprecated PreferenceActivity instead. sighDemisemiquaver
M
86

UPDATE - 6/11/2015

Support-v7 library now includes PreferenceFragmentCompat. So it will be a better idea to use it.


Add the following project as a library project to your application.

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

You can keep everything including your fragment transaction as it is. When importing the PreferenceFragment class, make sure the correct import header is user.

import android.support.v4.preference.PreferenceFragment;

instead of

import android.preference.PreferenceFragment;
Mercurate answered 22/12, 2013 at 8:15 Comment(9)
This worked great so far. Thanks for the info! Please make the link to github.com/kolavar/android-support-v4-preferencefragment more visible. Difficult to find the actual link. I'm on Chrome.Brockington
That github code seems to have serious issues... I cannot use RingtonePreference and also OnSharedPreferenceChangeListener does not seem to get any changes!Mongeau
I was thinking that it's a good idea to use this library. But i realized that it's not as good as i thought. Trying to override onPrepareOptionMenu method shows me a strange signature (returns void) different to the default one we all know (returns boolean) !!! a serious issue.Chromatism
upvoted, and you are entitled to a free dinner whenever you come to Madrid ... this issue was driving me crazy!Capitally
@mansoulx onPrepareOptionsMenu always has a void return type on fragments (unlike for Activities, for which it is boolean), so this signature is entirely as expected.Powe
getting this exeption while opening an alert dialog. I would before stick with the PrefernceActivity instead. android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application at android.view.ViewRootImpl.setView(ViewRootImpl.java:589) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)Clingy
Issues with the library should probably be reported on the github project.Midbrain
If anyone's like me, this is the dependency they are looking for: compile 'com.android.support:preference-v7:23.4.0'Koslo
1. Information on current versions of support libraries (to be used for Gradle builds), including v4 and v7 Preference Support Libraries is here: developer.android.com/topic/libraries/support-library/… 2. There is no support for RingtonePreference. For a workaround see: code.google.com/p/android/issues/detail?id=183255 After spending a couple of hours converting my code to use PreferenceFragmentCompat I returned back to android.preference.PreferenceFragment, because there is no support for preference headers (shown in their own fragment...)Concavoconvex
S
16

Important Update: The latest revision of the v7 support library now has a native PreferenceFragmentCompat.

I am using this library, which has an AAR in mavenCentral so you can easily include it if you are using Gradle.

compile 'com.github.machinarius:preferencefragment:0.1.1'

Semiweekly answered 17/3, 2014 at 18:39 Comment(4)
Could you share how you import and extend the support fragment? ThanksVaden
@Steve Sure! I made a Gist.Semiweekly
@mattblang Thanks alot... Your help really save my lot of timeRetro
Exception java.lang.RuntimeException: Content has view with id attribute 'android.R.id.list' that is not a ListView classGarboard
S
10

You can use my own PreferenceFragment.

It's simple and I had no issues with it so far. I think you can only display one of them at a time in a single Activity, which should be OK.

Silverware answered 7/8, 2014 at 16:32 Comment(0)
B
9

Preferences Support Library: Preference Fragments for API 7+, no matter the Activity

A simple implementation would include a PreferenceFragmentCompat such as:

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

You’ll also need to set preferenceTheme in your theme:

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

And add this in dependencies: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0
Branks answered 27/2, 2016 at 4:12 Comment(0)
E
7

You coul maybe use a real activity and use fragment, but I don't think it's a good choice. You should use simple PreferenceActivity and wait for improvements in retro compat libs.

Elegant answered 20/3, 2012 at 8:20 Comment(2)
I cannot use a PreferenceActivity as the rest of my app consists of a tabwidget. The preferencefragment is supposed to be shown above the tabwidget. I was to make it an activity instead it would take up the entire screen.Hereunder
Then use some custom list fragmentEmbouchure
C
2

You can use third party libraries such as UnifiedPreferences to use a single API for all versions of Android.

Concertize answered 14/11, 2013 at 13:51 Comment(0)
F
0

You can extend from PreferenceActivity instead, and if you wish to have an ActionBar, you can add it using a Toolbar as being above the ListView used for the preferences.

This can be done by using a vertical LinearLayout which holds the Toolbar and a ListView with android:id="@android:id/list" .

If you wish, you can see my solution here .

Furr answered 28/11, 2014 at 13:6 Comment(0)
B
0

As Lucius said you can use PreferenceFragmentCompat :

public class MyPreferenceFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle bundle, String s) {               
            PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
            addPreferencesFromResource(R.xml.preferences);
       }
}

You must include its dependency in gradle:

dependencies {
...
    compile 'com.android.support:preference-v7:23.1.X' (wherX = 0,1,...)
...
}

This way you can also can use FragmentTransaction of android.support.v4.app.FragmentTransaction and PrefernceFragment. However, you maybe have problems with themes. If it is the case, you can solve it having into account this post:

Solution to make the lib work on API 7+ while keeping material theme on API 14+

Broaddus answered 17/2, 2016 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.