Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android - How to set custom layout for PreferenceActivity in Android 3.0?

I am developing app with minSdkVersion="11", that is app for tablets and Android 4.0 and newer. I have scrutinized internet on this topic, but have not found much.

To implement custom layout for previous versions of Android SDK we just have to create layout (say preference.xml) with ListView and its id equals to android.R.id.list and use setContentView method.

preference.xml:

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

In Android 3.0 things have changed and Preferences are implemented with use of fragments. That is how my preference_headers.xml file looks like:

<preference-headers
        xmlns:android="http://schemas.android.com/apk/res/android">

    <header android:fragment="com.example.MyPreferenceActivity$GeneralSettingsFragment" 
            android:title="General"
            android:summary="Common settings." />
    <header  
            android:title="Example.com" >
        <intent android:action="android.intent.action.VIEW"
                android:data="http://www.example.com" />
    </header> 

</preference-headers>

MyPreferenceActivity.java:

public class MyPreferenceActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.preference);
        // Add a button to the header list.
        if (hasHeaders()) {
            Button button = new Button(this); 
            button.setText("Log out");
            setListFooter(button);

        }

    }


    /**
     * Populate the activity with the top-level headers.
     */
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preference_headers, target);
    }

    public static class GeneralSettingsFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

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

        }
    }
}

Now if I run MyPreferenceActivity I will see this error in LogCat:

> java.lang.IllegalArgumentException: No view found for id 0x10202be for
> fragment GeneralSettingsFragment{4077f8c0 #0 id=0x10202be}
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:729)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:926)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:909)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1584)
> E/AndroidRuntime(17103): at
> android.app.Activity.performStart(Activity.java:4377)
> E/AndroidRuntime(17103): at
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1724)
> E/AndroidRuntime(17103):  ... 11 more

I know what causes this problem. FragmentManager just cannot find a view to insert fragment GeneralSettingsFragment in. But I don't know how to solve it.

By the way, if I run the same app on Android 4.0, then I can see the first Preference Activity with headers. But if I click on General, app will crash and I will receive similar error in LogCat:

java.lang.IllegalArgumentException: No view found for id 0x10202cd for fragment GeneralSettingsFragment{4134b4e0 #0 id=0x10202cd}
E/AndroidRuntime(2170):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:789)
E/AndroidRuntime(2170):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:998)
E/AndroidRuntime(2170):     at android.app.BackStackRecord.run(BackStackRecord.java:622)
E/AndroidRuntime(2170):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1330)
E/AndroidRuntime(2170):     at android.app.Activity.performStart(Activity.java:4474)
E/AndroidRuntime(2170):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1928)
like image 954
morphium Avatar asked Oct 21 '11 08:10

morphium


2 Answers

I had the same issue than you.

I tried a lot of stuff but here is my full code:

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/MyPreferenceActivity.java

The trick is to add the setContentView in the onBuildHeaders section, but NOT in the onCreate.

I also made some tests in fragment and not perfectly sure why this is working, but I promise you: I have a custom layout on tablet header section!

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/view/StockPreferenceFragment.java

like image 160
Waza_Be Avatar answered Oct 20 '22 06:10

Waza_Be


i tried this code for my application

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="@string/PreferencesActivity.GeneralSettingsCategoryTitle">
        <Preference
            android:title="yor title"
            android:summary="your summary"
            android:key="key to access preference" />       
        <Preference
            android:title="@string/"
            android:summary="@string/"
            android:key="key2" />
        <PreferenceScreen
            android:key="key3"
            android:title="@string/"
            android:summary="@string/">
            <CheckBoxPreference
                android:title="@string/"
                android:defaultValue="false"
                android:summary="@string/"
                android:key="key4" />
            <CheckBoxPreference
                android:title="@string/"
                android:defaultValue="true"
                android:summary="@string/"
                android:key="key5" />

            <ListPreference
                android:title="@string/"
                android:summary="@string/"
                android:key="key6"
                android:defaultValue="buttons"
                android:entries="@array/"
                android:entryValues="@array/" />
            ....


                </prefefenceScreen>
      </preferenceCategory>
</preferenceScreen>



enter code here
like image 43
Pratik Popat Avatar answered Oct 20 '22 05:10

Pratik Popat