Question

I am trying to create a custom preference setting to show a dialog box with a dropdown menu to allow users to choose their preference.

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:key="notification_settings"
        android:title="@string/notifications">
        <CheckBoxPreference
            android:key="pref_send_notification"
            android:title="@string/pref_switch_notification"
            android:summary="@string/pref_switch_notification"
            android:defaultValue="true" />

        <ListPreference
            android:key="updates_interval"
            android:title="Updates interval"
            android:summary="Define how often updates will be performed"
            android:defaultValue="1000"
            android:entries="@array/updateInterval"
            android:entryValues="@array/updateIntervalValues"
            android:dependency="perform_updates"
        />   

        <DialogPreference.distancePreference
            android:dependency="pref_sync"
            android:key="pref_indicate_proximity"
            android:title="@string/pref_proximity"
            android:dialogTitle="@string/pref_proximity"
            android:entries="@array/category_names"
            android:entryValues="@array/category_names"
            android:defaultValue="@string/pref_proximity" />
    </PreferenceCategory>
</PreferenceScreen>

This is the code for my distance preference:

package com.example.makemyday;

import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;

public class distancePreference extends DialogPreference {

     private Context context;
     private Spinner categories;
     private ArrayAdapter<CharSequence> adapter;     

        public distancePreference(Context context, AttributeSet attrs) {              
            super(context, attrs);      
            this.context = context;
            setPersistent(false);
            setDialogLayoutResource(R.layout.preference_distance);
        }


        @Override
        protected void onBindDialogView(View view) {        
            categories = (Spinner) view.findViewById(R.id.category_preference);


            adapter = ArrayAdapter.createFromResource(context, R.array.category_names, android.R.layout.simple_spinner_dropdown_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //simple_spinner_dropdown_item simple_spinner_item
            categories.setAdapter(adapter);
            categories.setSelection(0);

            super.onBindDialogView(view);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            LayoutInflater inflater = LayoutInflater.from(context);
            LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.preference_distance , null);
            linearLayout.removeView(categories);
            super.onDismiss(dialog);
        }

        @Override
        protected void onDialogClosed(boolean positiveResult) {
            super.onDialogClosed(positiveResult);
            if (positiveResult) {
                SharedPreferences.Editor editor = getEditor();
                editor.putString(getKey() + ".type", categories.getSelectedItem().toString());
                editor.commit();       
            }
        }
}

UserSettingsActivity:

package com.example.makemyday;

import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.view.Menu;
import android.view.MenuItem;

public class UserSettingsActivity extends PreferenceActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       getFragmentManager().beginTransaction().replace(android.R.id.content, new UserPreferenceFragment()).commit();
    }

     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         menu.add(Menu.NONE, 0, 0, "Show current settings");
         return super.onCreateOptionsMenu(menu);
     }

     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case 0:
                 startActivity(new Intent(this, MainActivity.class));
                 return true;
         }
         return false;
     }

    public static class UserPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }

    }
}

When I run the code and click on settings, I get the following error:

02-07 17:54:12.204: E/AndroidRuntime(15780): FATAL EXCEPTION: main
02-07 17:54:12.204: E/AndroidRuntime(15780): Process: com.example.makemyday, PID: 15780
02-07 17:54:12.204: E/AndroidRuntime(15780): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.makemyday/com.example.makemyday.UserSettingsActivity}: android.view.InflateException: Binary XML file line #22: Error inflating class DialogPreference.distancePreference
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.os.Looper.loop(Looper.java:136)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread.main(ActivityThread.java:5017)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at java.lang.reflect.Method.invokeNative(Native Method)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at java.lang.reflect.Method.invoke(Method.java:515)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at dalvik.system.NativeStart.main(Native Method)
02-07 17:54:12.204: E/AndroidRuntime(15780): Caused by: android.view.InflateException: Binary XML file line #22: Error inflating class DialogPreference.distancePreference
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:441)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.rInflate(GenericInflater.java:481)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.rInflate(GenericInflater.java:493)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.inflate(GenericInflater.java:326)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.inflate(GenericInflater.java:263)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:272)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.PreferenceFragment.addPreferencesFromResource(PreferenceFragment.java:285)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at com.example.makemyday.UserSettingsActivity$UserPreferenceFragment.onCreate(UserSettingsActivity.java:40)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.Fragment.performCreate(Fragment.java:1678)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:859)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.BackStackRecord.run(BackStackRecord.java:684)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.Activity.performStart(Activity.java:5240)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
02-07 17:54:12.204: E/AndroidRuntime(15780):    ... 11 more
02-07 17:54:12.204: E/AndroidRuntime(15780): Caused by: java.lang.ClassNotFoundException: Didn't find class "DialogPreference.distancePreference" on path: DexPathList[[zip file "/system/framework/com.google.android.maps.jar", zip file "/data/app/com.example.makemyday-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.makemyday-2, /vendor/lib, /system/lib]]
02-07 17:54:12.204: E/AndroidRuntime(15780):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.createItem(GenericInflater.java:375)
02-07 17:54:12.204: E/AndroidRuntime(15780):    at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:430)

Could someone explain what's going on?

Was it helpful?

Solution

You have to use the full class name including package in your layout. it's com.example.makemyday.distancePreference

    <com.example.makemyday.distancePreference
        android:dependency="pref_sync"
        android:key="pref_indicate_proximity"
        android:title="@string/pref_proximity"
        android:dialogTitle="@string/pref_proximity"
        android:entries="@array/category_names"
        android:entryValues="@array/category_names"
        android:defaultValue="@string/pref_proximity" />

Apart from that, you can follow for example http://viralpatel.net/blogs/android-preferences-activity-example/ to implement the PreferenceScreen in a appropriate way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top