3

好吧,现在我知道这个问题在SO之前已经被问过几次了,但是没有一个答案对我有用。使用java.lang.ClassNotFoundException膨胀布局时出错

我正在尝试为我的项目创建一个自定义首选项。更具体地说,它是直接连接在它下面的HorizontalListView。我基本上通过修改this code来创建SeekBarPreference(我也在使用它并且工作正常)。我的ListViewPreference位于与SeelkBarPreference完全相同的文件夹中(正如我所说没有问题),但我不断得到ClassNotFoundException(请参阅下面的logcat)。这里是我ListViewPreference类:

package com.example.ebookreader; 

import android.content.Context; 
import android.content.res.TypedArray; 
import android.preference.Preference; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.ViewGroup.LayoutParams; 
import android.view.ViewParent; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

public class ListViewPreference extends Preference { 

    private final String TAG = getClass().getName(); 

    private static final String ROBOBUNNYNS = "http://robobunny.com"; 
    private static final int DEFAULT_VALUE = 50; 

    private int mCurrentValue; 
    private String mUnitsLeft = ""; 
    private String mUnitsRight = ""; 

    private HorizontalListView mListView; 

    private TextView mStatusText; 

    public ListViewPreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     initPreference(context, attrs); 
    } 

    public ListViewPreference(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     initPreference(context, attrs); 
    } 

    private void initPreference(Context context, AttributeSet attrs) { 
     setValuesFromXml(attrs); 

     mListView = new HorizontalListView(context, attrs); 
     LayoutParams params = mListView.getLayoutParams(); 
     params.width = LayoutParams.MATCH_PARENT; 
     params.height = LayoutParams.WRAP_CONTENT; 
     mListView.setLayoutParams(params); 
    } 

    private void setValuesFromXml(AttributeSet attrs) { 
     mUnitsLeft = getAttributeStringValue(attrs, ROBOBUNNYNS, "unitsLeft", 
       ""); 
     String units = getAttributeStringValue(attrs, ROBOBUNNYNS, "units", ""); 
     mUnitsRight = getAttributeStringValue(attrs, ROBOBUNNYNS, "unitsRight", 
       units); 
    } 

    private String getAttributeStringValue(AttributeSet attrs, 
      String namespace, String name, String defaultValue) { 
     String value = attrs.getAttributeValue(namespace, name); 

     if (value == null) 
      value = defaultValue; 

     return value; 
    } 

    @Override 
    protected View onCreateView(ViewGroup parent) { 
     RelativeLayout layout = null; 

     try { 
      LayoutInflater mInflater = (LayoutInflater) getContext() 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

      layout = (RelativeLayout) mInflater.inflate(
        R.layout.horizontal_list_view_preference, parent, false); 
     } catch (Exception e) { 
      Log.e(TAG, "Error creating seek bar preference", e); 
     } 

     return layout; 
    } 

    @Override 
    public void onBindView(View view) { 
     super.onBindView(view); 

     try { 
      // move our seekbar to the new view we've been given 
      ViewParent oldContainer = mListView.getParent(); 
      ViewGroup newContainer = (ViewGroup) view 
        .findViewById(R.id.listViewPrefBarContainer); 

      if (oldContainer != newContainer) { 
       // remove the seekbar from the old view 
       if (oldContainer != null) { 
        ((ViewGroup) oldContainer).removeView(mListView); 
       } 
       // remove the existing seekbar (there may not be one) and add 
       // ours 
       newContainer.removeAllViews(); 
       newContainer.addView(mListView, 
         ViewGroup.LayoutParams.FILL_PARENT, 
         ViewGroup.LayoutParams.WRAP_CONTENT); 
      } 
     } catch (Exception ex) { 
      Log.e(TAG, "Error binding view: " + ex.toString()); 
     } 

     updateView(view); 
    } 

    /** 
    * Update a SeekBarPreference view with our current state 
    * 
    * @param view 
    */ 
    protected void updateView(View view) { 
     try { 
      RelativeLayout layout = (RelativeLayout) view; 

      mStatusText = (TextView) layout 
        .findViewById(R.id.listViewPrefValue); 
      mStatusText.setText(String.valueOf(mCurrentValue)); 
      mStatusText.setMinimumWidth(30); 

      TextView unitsRight = (TextView) layout 
        .findViewById(R.id.listViewPrefUnitsRight); 
      unitsRight.setText(mUnitsRight); 

      TextView unitsLeft = (TextView) layout 
        .findViewById(R.id.listViewPrefUnitsLeft); 
      unitsLeft.setText(mUnitsLeft); 
     } catch (Exception e) { 
      Log.e(TAG, "Error updating seek bar preference", e); 
     } 
    } 

    @Override 
    protected Object onGetDefaultValue(TypedArray ta, int index) { 
     int defaultValue = ta.getInt(index, DEFAULT_VALUE); 
     return defaultValue; 
    } 

    @Override 
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 
     if (restoreValue) { 
      mCurrentValue = getPersistedInt(mCurrentValue); 
     } else { 
      int temp = 0; 
      try { 
       temp = (Integer) defaultValue; 
      } catch (Exception ex) { 
       Log.e(TAG, "Invalid default value: " + defaultValue.toString()); 
      } 

      persistInt(temp); 
      mCurrentValue = temp; 
     } 
    } 
} 

对于大多数人来说这个问题是不具有参数ContextAttributeSet构造函数的结果,但你可以看到,我已清楚它。

下面是XML文件,其中的错误不断发生:

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:custom="http://schemas.android.com/apk/res/com.example.ebookreader" 
    android:background="@drawable/wallpaper" > 

    <android:PreferenceCategory 
     android:key="device_settings" 
     android:title="Device Settings" > 

     <android:CheckBoxPreference 
      android:key="wifi" 
      android:summary="Enable or Disable Wi-Fi" 
      android:title="Wi-Fi" /> 

     <android:CheckBoxPreference 
      android:key="bluetooth" 
      android:summary="Enable or Disable Bluetooth" 
      android:title="Bluetooth" /> 

     <android:CheckBoxPreference 
      android:key="autosync" 
      android:summary="Enable or Disable AutoSync" 
      android:title="AutoSync" /> 

     <custom:SeekBarPreference 
      android:id="@+id/brightness_adjust" 
      android:defaultValue="100" 
      android:key="brightness" 
      android:max="200" 
      android:summary="Adjust Brightness Levels" 
      android:title="Brightness" /> 
    </android:PreferenceCategory> 

    <android:PreferenceCategory 
     android:key="account_settings" 
     android:title="Account Settings" > 

     <custom:ListViewPreference> <!-- Error happens here --> 
       android:id="@+id/font_selector" 
       android:key="font" 
       android:title="Font" 
       android:summary="Edit Font"  
      /> 
     </custom:ListViewPreference> 
    </android:PreferenceCategory> 

</PreferenceScreen> 

下面是我的全部的logcat:

03-14 17:53:14.290: E/AndroidRuntime(449): FATAL EXCEPTION: main 
03-14 17:53:14.290: E/AndroidRuntime(449): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ebookreader/com.example.ebookreader.SettingsActivity}: android.view.InflateException: Binary XML file line #40: Error inflating class ListViewPreference 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1736) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1752) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread.access$1500(ActivityThread.java:123) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:993) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.os.Handler.dispatchMessage(Handler.java:99) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.os.Looper.loop(Looper.java:126) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread.main(ActivityThread.java:3997) 
03-14 17:53:14.290: E/AndroidRuntime(449): at java.lang.reflect.Method.invokeNative(Native Method) 
03-14 17:53:14.290: E/AndroidRuntime(449): at java.lang.reflect.Method.invoke(Method.java:491) 
03-14 17:53:14.290: E/AndroidRuntime(449): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
03-14 17:53:14.290: E/AndroidRuntime(449): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
03-14 17:53:14.290: E/AndroidRuntime(449): at dalvik.system.NativeStart.main(Native Method) 
03-14 17:53:14.290: E/AndroidRuntime(449): Caused by: android.view.InflateException: Binary XML file line #40: Error inflating class ListViewPreference 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:441) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.rInflate(GenericInflater.java:481) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.rInflate(GenericInflater.java:493) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.inflate(GenericInflater.java:326) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.inflate(GenericInflater.java:263) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:269) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.PreferenceActivity.addPreferencesFromResource(PreferenceActivity.java:1333) 
03-14 17:53:14.290: E/AndroidRuntime(449): at com.example.ebookreader.SettingsActivity.onCreate(SettingsActivity.java:31) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1700) 
03-14 17:53:14.290: E/AndroidRuntime(449): ... 11 more 
03-14 17:53:14.290: E/AndroidRuntime(449): Caused by: java.lang.ClassNotFoundException: android.preference.ListViewPreference in loader dalvik.system.PathClassLoader[/data/app/com.example.ebookreader-2.apk] 
03-14 17:53:14.290: E/AndroidRuntime(449): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:251) 
03-14 17:53:14.290: E/AndroidRuntime(449): at java.lang.ClassLoader.loadClass(ClassLoader.java:548) 
03-14 17:53:14.290: E/AndroidRuntime(449): at java.lang.ClassLoader.loadClass(ClassLoader.java:508) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.createItem(GenericInflater.java:375) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.onCreateItem(GenericInflater.java:417) 
03-14 17:53:14.290: E/AndroidRuntime(449): at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:428) 
03-14 17:53:14.290: E/AndroidRuntime(449): ... 20 more 

任何帮助将不胜感激。

回答

5

但为什么要这么写

<custom:ListViewPreference 

应该

<com.example.ebookreader.ListViewPreference 

当你的包,其中的类放置,称为

+0

这做到了。谢谢。 – 2013-03-15 13:13:16

4

一般情况下,你需要使用的完整路径组件:

<com.example.ebookreader.ListViewPreference 
    android:id="@+id/font_selector" 
    android:key="font" 
    android:title="Font" 
    android:summary="Edit Font"  
/> 

我从来没见过使用“自定义:”作为一个元素。