这是我第一次创建自定义 View ,并且尝试通过XML填充条目,其方式类似于Spinner。我显然在这里做错了什么,但是我在Spinner之后设置了样式,所以我看不到出了什么问题。
为了解释此代码的 Intent ,我创建了一个自定义首选项列表。 MultiChooserOption是一项允许用户从选项列表中选择多项的项目。 TextOption仅定义将在列表中显示的 View ,即-是标题和其他元素,对于TextOption的子类,其他元素将是文本,而不是小部件(复选框等)。
以下是应该对我的构建方式以及logcat输出产生任何影响的所有内容的来源。
attrs.xml
<resources>
<attr name="caption" format="string" />
<attr name="options" format="reference" />
<declare-styleable name="TextOption">
<attr name="caption" />
<attr name="text" format="string" />
</declare-styleable>
<declare-styleable name="MultiChooserOption">
<attr name="options" />
</declare-styleable>
</resources>
MultiChooserOption.java
public class MultiChooserOption extends TextOption<CharSequence> {
public static final String TAG = MultiChooserOption.class.getSimpleName();
private List<CharSequence> options;
private MultiChoiceListView<CharSequence> choiceView;
public MultiChooserOption(Context context) {
super( context );
}
public MultiChooserOption(Context context, AttributeSet attrs) {
super( context, attrs );
initOptions( attrs );
}
private void initOptions( AttributeSet attrs ) {
TypedArray attributesArray = getContext().obtainStyledAttributes( attrs, R.styleable.TextOption, 0, 0 );
try {
// this line is where things go wrong
CharSequence[] optionsArray = attributesArray.getTextArray( R.styleable.MultiChooserOption_options );
setOptions( Arrays.asList( optionsArray ) );
}
catch (NotFoundException e) {
Log.e( TAG, e.getMessage(), e );
}
finally {
attributesArray.recycle();
}
}
}
TextOption.java
public abstract class TextOption<T> extends LinearLayout {
public static final String TAG = TextOption.class.getSimpleName();
private TextView captionTextView;
private TextView valueTextView;
private String caption;
private String value;
public TextOption(Context context) {
super( context );
init();
}
public TextOption(Context context, AttributeSet attrs) {
super( context, attrs );
TypedArray attributesArray = context.obtainStyledAttributes( attrs, R.styleable.TextOption, 0, 0 );
try {
setCaption( attributesArray.getString( R.styleable.TextOption_caption ) );
setValue( attributesArray.getString( R.styleable.TextOption_text ) );
}
finally {
attributesArray.recycle();
}
init();
}
}
options_fragment.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.mypackage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.mypackage.view.MultiChooserOption
android:id="@+id/multichooser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:caption="@string/multichooser_caption"
custom:options="@array/multichooser_options" />
</LinearLayout>
</ScrollView>
arrays.xml
<resources>
<string-array name="multichooser_options">
<item>@string/option1</item>
<item>@string/option2</item>
<item>@string/option3</item>
<item>@string/option4</item>
<item>@string/option5</item>
<item>@string/option6</item>
</string-array>
</resources>
strings.xml
<resources>
<string name="multichooser_caption">MultiChooser</string>
<string name="option1">option 1</string>
<string name="option2">option 2</string>
<string name="option3">option 3</string>
<string name="option4">option 4</string>
<string name="option5">option 5</string>
<string name="option6">option 6</string>
</resources>
OptionsFragment.java
public class OptionsFragment extends RoboSherlockFragment {
public static final String TAG = OptionsFragment.class.getSimpleName();
@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
View view = inflater.inflate( R.layout.options_fragment, container, false );
return view;
}
}
logcat输出
09-18 20:52:36.940: E/AndroidRuntime(4237): FATAL EXCEPTION: main
09-18 20:52:36.940: E/AndroidRuntime(4237): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage/com.mypackage.ui.OptionsActivity}: android.view.InflateException: Binary XML file line #44: Error inflating class com.mypackage.view.MultiChooserOption
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.os.Handler.dispatchMessage(Handler.java:99)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.os.Looper.loop(Looper.java:137)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-18 20:52:36.940: E/AndroidRuntime(4237): at java.lang.reflect.Method.invokeNative(Native Method)
09-18 20:52:36.940: E/AndroidRuntime(4237): at java.lang.reflect.Method.invoke(Method.java:511)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-18 20:52:36.940: E/AndroidRuntime(4237): at dalvik.system.NativeStart.main(Native Method)
09-18 20:52:36.940: E/AndroidRuntime(4237): Caused by: android.view.InflateException: Binary XML file line #44: Error inflating class com.mypackage.view.MultiChooserOption
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.createView(LayoutInflater.java:613)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.mypackage.ui.OptionsFragment.onCreateView(OptionsFragment.java:27)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.github.rtyley.android.sherlock.roboguice.activity.RoboSherlockFragmentActivity.onStart(RoboSherlockFragmentActivity.java:46)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.Activity.performStart(Activity.java:5114)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2153)
09-18 20:52:36.940: E/AndroidRuntime(4237): ... 11 more
09-18 20:52:36.940: E/AndroidRuntime(4237): Caused by: java.lang.reflect.InvocationTargetException
09-18 20:52:36.940: E/AndroidRuntime(4237): at java.lang.reflect.Constructor.constructNative(Native Method)
09-18 20:52:36.940: E/AndroidRuntime(4237): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.view.LayoutInflater.createView(LayoutInflater.java:587)
09-18 20:52:36.940: E/AndroidRuntime(4237): ... 27 more
09-18 20:52:36.940: E/AndroidRuntime(4237): Caused by: java.lang.NullPointerException
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.content.res.AssetManager.getResourceTextArray(AssetManager.java:214)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.content.res.Resources.getTextArray(Resources.java:427)
09-18 20:52:36.940: E/AndroidRuntime(4237): at android.content.res.TypedArray.getTextArray(TypedArray.java:628)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.mypackage.view.MultiChooserOption.initOptions(MultiChooserOption.java:42)
09-18 20:52:36.940: E/AndroidRuntime(4237): at com.mypackage.view.MultiChooserOption.<init>(MultiChooserOption.java:32)
09-18 20:52:36.940: E/AndroidRuntime(4237): ... 30 more
因此,当执行MultiChooserOption中的
CharSequence[] optionsArray = attributesArray.getTextArray( R.styleable.MultiChooserOption_options );
行时,将引发异常,并且整个shebang都将崩溃。据我所知,我尽可能关注Spinner。请帮助我了解我在这里做错了什么。
最佳答案
好吧,现在我觉得很傻。
扩展父级 View 时,获取父级的样式化属性不是一个好主意。TypedArray attributesArray = getContext().obtainStyledAttributes( attrs, R.styleable.TextOption, 0, 0 );
应该TypedArray attributesArray = getContext().obtainStyledAttributes( attrs, R.styleable.MultiChooserOption, 0, 0 );
关于java - TypedArray#getTextArray()期间引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18885132/