0

button私は拡張する習慣がありますView。コンストラクターでは、XML定義で設定されたカスタム属性を保持するようにメンバー変数を設定しています。現在、XMLで定義されているこれらのボタンは5つあり、それぞれにステージを表すために異なるintが付加されています。

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.mycompany.stagedApp"
android:layout_width="match_parent"
android:orientation="horizontal"
style="@style/stepFooter">

<com.mycompany.stagedApp.StepButtonView
    android:text="@string/step_one_icon"
    style="@style/numberedIcon"
    android:id="@+id/step_one_button"
    custom:stepNumber="1"
    android:background="@drawable/circle" />
<com.mycompany.stagedApp.StepButtonView
    android:text="@string/step_two_icon"
    style="@style/numberedIcon"
    android:id="@+id/step_two_button"
    custom:stepNumber="2"
    android:background="@drawable/circle" />
<com.mycompany.stagedApp.StepButtonView
    android:text="@string/step_three_icon"
    style="@style/numberedIcon"
    android:id="@+id/step_three_button"
    custom:stepNumber="3"
    android:background="@drawable/circle" />
<com.mycompany.stagedApp.StepButtonView
    android:text="@string/step_four_icon"
    style="@style/numberedIcon"
    android:id="@+id/step_four_button"
    custom:stepNumber="4"
    android:background="@drawable/circle" />
<com.mycompany.stagedApp.StepButtonView
    android:text="@string/step_five_icon"
    style="@style/numberedIcon"
    android:id="@+id/step_five_button"
    custom:stepNumber="5"
    android:background="@drawable/circle" />
</LinearLayout>

StepButtonView.java私は持っています:

class StepButtonView extends View {

  private static int stepNumber;

  public StepButtonView(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.custom_values);
    stepNumber = ta.getInt(R.styleable.custom_values_stepNumber, 0);

    // This log correctly displays the numbers 1 - 5
    Log.d("StepFromCustom in constructor", String.format("%d",StepButtonView.stepNumber));

    this.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View view) {
            Log.d("Step", String.format("%d", view.getId()));
            // This log only displays the last number 5
            Log.d("StepFromCustom", String.format("%d",StepButtonView.stepNumber));
        }
    });
  }
}

開始して各ボタンが作成されると、activity1〜5の数字がログに記録されます。ただし、クリックすると、ログに記録される数は常に5、最後になりstepNumberます。onClick listenerそこには異なるID値がリストされていますが、同じでstepNumberあるため、同じオブジェクトを参照しているという私の最初の考えは正しくないはずです。

誰かが何が起こっているのか、そしてその理由を説明してもらえますか?これは私が明らかにする必要のある言語の誤解だと思います。

4

1 に答える 1

4

それはあなたstepNumberがだからですstatic。つまり、これはクラス変数であり、設定される最後の値(最後のコンストラクターButton)であるため、5のままになります。それを削除すると問題が解決します。

アプリケーションを実行してみましょう:

  • 最初のコンストラクター:stepNumberは1です。
  • 2番目のコンストラクター:stepNumberは2です。
  • 3番目のコンストラクター:stepNumberは3です。
  • 4番目のコンストラクター:stepNumberは4です。
  • 5番目のコンストラクター:stepNumberは5です。

この後、それはもう設定されていないので、5のままになります。

  • その後ごとonClickに:Log.d()5を出力します

編集:コメントを見ると、おそらくfinal属性を意味しますが、これは変更できず、コンストラクターでのみ設定できます。コンストラクターで既に設定しているので、それを属性に追加して、次のようにするのはまったく問題ありません。

private final int stepNumber;

Edit2:staticメンバーは特定のインスタンスではなくクラスに属します。

これは、クラスのインスタンスを100万個作成した場合、または作成しなかった場合でも、フィールドのインスタンスが1つだけ存在することを意味します。staticすべてのインスタンスで共有されます。

于 2013-01-21T15:07:25.950 に答える