Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 905
Ben987654 Avatar asked May 12 '16 19:05

Ben987654


1 Answers

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.

like image 72
tynn Avatar answered Oct 10 '22 03:10

tynn