6

カスタム ビューを作成するのはこれが初めてで、Spinner と同様の方法で、XML 経由でエントリを入力しようとしています。ここでは明らかに何か間違ったことをしていますが、Spinner の後にアプローチをスタイルしているので、何が間違っているのかわかりません。

このコードの意図を説明するために、カスタム設定リストを作成しています。MultiChooserOption は、ユーザーがオプションのリストから複数のものを選択できるようにするアイテムです。TextOption は、リストに表示されるビューを定義するだけです。つまり、キャプションとその他の要素があり、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>

配列.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>

文字列.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

CharSequence[] optionsArray = attributesArray.getTextArray( R.styleable.MultiChooserOption_options );そのため、MultiChooserOptionの行が実行されると、例外がスローされ、シバン全体が崩壊します。私が知る限り、私は重要な限り Spinner をフォローしています。

ここで私が間違ったことを学ぶのを手伝ってください。

4

1 に答える 1

3

さて、私はばかげていると感じています。

親ビューを拡張する場合、親のスタイル属性を取得することはお勧めできません。

TypedArray attributesArray = getContext().obtainStyledAttributes( attrs, R.styleable.TextOption, 0, 0 );

する必要があります

TypedArray attributesArray = getContext().obtainStyledAttributes( attrs, R.styleable.MultiChooserOption, 0, 0 );

于 2013-09-19T15:45:01.797 に答える