PreferenceFragmentCompat won't load in AppCompatPreferenceActivity - Trying to instantiate a class that is not a Fragment
M

2

5

I'm trying to use PreferenceFragmentCompat from the v7 support library. When I try to add it, it always returns the following exception

Process: com.sample.preferencetest, PID: 14444
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sample.preferencetest/com.sample.preferencetest.SettingsActivity}: android.app.Fragment$InstantiationException: Trying to instantiate a class com.sample.preferencetest.SettingsActivity$EmptyFragment that is not a Fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3155)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3263)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6897)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

When I try to use a PreferenceFragment with this, everything works fine. It's only when I try to use the PreferenceFragmentCompat that it fails

The reason I want to use this, is because the onAttach(Activity) method is now deprecated, and earlier devices weren't attaching my interface.

This is the class

package com.sample.preferencetest;

import android.os.Bundle;
//import android.preference.PreferenceFragment;  I toggle this to try regular preference fragments.
import android.support.v7.preference.PreferenceFragmentCompat;
import java.util.List;

public class SettingsActivity extends AppCompatPreferenceActivity {

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

    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.pref_headers, target);
    }

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

    public static class EmptyFragment extends PreferenceFragmentCompat {
        public EmptyFragment() {
        }

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

        @Override
        public void onCreatePreferences(Bundle bundle, String s) {
        }
    }
}

Headers XML

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
    android:fragment="com.sample.preferencetest.SettingsActivity$EmptyFragment"
    android:icon="@drawable/ic_info_black_24dp"
    android:title="@string/pref_header_general" />
</preference-headers>

Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.sample.preferencetest"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    compile 'com.android.support:support-v4:23.2.1'
    compile 'com.android.support:preference-v7:23.3.0'
}

How am I supposed to use the PreferenceFragmentCompat, if not this way?

Monotonous answered 12/5, 2016 at 19:12 Comment(1)
onAttach(Activity activity) is deprecated. Use instead onAttach(Context context). Works in both casesBolzano
G
8

This problem occurs, because framework fragments and support fragments are not compatible. If you're using the AppCompatPreferenceActivity from the samples of the support library, you're using a normal PreferenceActivity with toolbar support. Support fragments are not supported there. That's why PreferenceFragment works fine and PreferenceFragmentCompat doesn't.

If you're only concerned about onAttach(Activity) being deprecated, don't be. The default implementation of onAttach(Context) just calls through to it when attached to an activtiy. Therefore it's safe to only implement onAttach(Activity) to be compatible with all current versions of Android.

Gosse answered 12/8, 2016 at 9:48 Comment(6)
How load headers onBuildHeaders with PreferenceFragmentCompat and AppCompatPreferenceActivity ?Baalman
@Andreyua If it's the example AppCompatPreferenceActivity, you can't.Gosse
without AppCompatPreferenceActivity, but with PreferenceFragmentCompat ?Baalman
@Andreyua onBuildHeaders() was introduced with Honeycomb for PreferenceFragment only. I don't know about a port for the support library. Read up on developer.android.com/guide/topics/ui/…Gosse
But PreferenceFragment not support material theme for API Level < 21 . Only PreferenceFragmentCompat - but without onBuildHeaders for supporting tablets. And - what the point?Baalman
@Andreyua this is not realy the point of this question, but a good one by itself. You should ask a new one and maybe leave the link here. I'd be interested in an answer to this as well.Gosse
C
-1

Add compile 'com.android.support:preference-v14:24.1.1' to gradle and use

android.support.v14.preference.PreferenceFragment 

instead of

android.support.v7.preference.PreferenceFragmentCompat.

This solved the problem for me.

Curvaceous answered 18/8, 2016 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.