2

だから私はアンドロイドで遊んでいて、行き止まりになりました。

その答えは私の問題の良い回避策になる可能性があるため、この質問はこれに関連している可能性がありますが、コードが失敗する理由に興味があります。ビューについて、いくつかの重大な誤解があるかもしれません。

だから、私はこのバックギャモンボードを持っています:

上下にチップが積み上げられたバックギャモンボード

すべての移動でアニメーションを実行したいと考えています。そのためには、画面上で移動チップの起点と終点の座標を取得する必要があります。

したがって、ポイントがスタックとして動作することを確認する必要があります。新しいビューは、逆さまのポイントの下部と逆さまのポイントの上部に挿入する必要があります。任意のポイントの重力は画面上の位置に応じて TOP または BOTTOM になるため、この属性を取得してこれを行うことができますが、非公開のようです:関連する投稿のこの回答を参照してください

だから私はカスタム LinearLayout を作成しました:

<resources>
<declare-styleable name="PointView">
    <attr name="upsideDown" format="boolean" />
</declare-styleable>
</resources>

LinearLayout をオーバーライドするもの

public class PointView extends LinearLayout {
    private boolean mUpsideDown = false;

public PointView(Context context) {
    super(context);
}

public PointView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs, 0);
}

public PointView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs, defStyle);
}

private void init(Context context, AttributeSet attrs, int defStyle) {

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PointView);

    mUpsideDown = a.getBoolean(R.styleable.PointView_upsideDown, false);
    a.recycle();
}

@Override
public View getChildAt(int index) {
    return mUpsideDown ? super.getChildAt(index) : super.getChildAt(super.getChildCount() - index + 1);
}

@Override
public void addView(View child) {
    if(mUpsideDown) {
        super.addView(child);
    }
    else {
        super.addView(child, 0);
    }
}
}

それらは、次のようにアクティビティの XML に含まれています。

<spacebar.backgammoid.PointView
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:background="@drawable/black_point"
                    android:layout_weight="1"
                    android:focusableInTouchMode="false"
                    android:id="@+id/point13"
                    android:weightSum="5"
                    android:clipChildren="false"
                    android:gravity="top"
                    app:upsideDown="true"/>

ここで、実行時に init() が呼び出されると、例外が発生します。

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.resolveLayoutParams()' on a null object reference

のコンテキストが null のようです:

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PointView);

理由がわからないので、カスタム属性 upsideDown にアクセスできません。

attrs からプロパティへのアクセスを取得しようとしています:

        attrs.getAttributeBooleanValue(R.styleable.PointView_upsideDown, false);

私には同義語のように見えますが、明らかにそうではありませんが、常に true を返します。

何か案が?

前もって感謝します

[編集]

例外のスタックトレース:

--------- beginning of crash
06-23 10:04:34.972    2036-2036/spacebar.backgammoid E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: spacebar.backgammoid, PID: 2036
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.resolveLayoutParams()' on a null object reference
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.ViewGroup.resolveLayoutParams(ViewGroup.java:6116)
        at android.view.View.setLayoutParams(View.java:11473)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:273)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3055)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395)
        at android.app.ActivityThread.access$800(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        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:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

[編集2]

プログラムでチップを使用してポイントを設定していましたが、アクティビティの XML に設定すると、設計時に同じ例外がスローされます。

<spacebar.backgammoid.PointView ...>
    <ImageView ... />
</spacebar.backgammoid.PointView>

それでも、カスタム ビューの代わりに通常の LinearLayouts を使用すると、すべて正常に動作し、エラーは発生しません。

<LinearLayout ...>
    <ImageView ... />
</LinearLayout>

また、関連性があるかどうかはわかりませんが、android-studio デザイナーは、PoinView でビューをネストすることを許可していません。

4

1 に答える 1