Reputation: 1201
I have a custom button
that extends View
. In the constructor I am setting a member variable to hold a custom attribute set in the XML definition. At the moment there are 5 of these buttons defined in the XML each with a different int attached to represent a stage.
<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>
In the StepButtonView.java
I have:
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));
}
});
}
}
When the activity
starts and each button is constructed the numbers 1 -5 are logged. However on click the number logged is always 5, the last stepNumber
. In the onClick listener
it lists a different ID value but the same stepNumber
so my initial thought that it was referring to the same object must be incorrect.
Could anyone explain what's going on, and why, as I think this is a misunderstanding with the language which I obviously need to clear up.
Upvotes: 0
Views: 1347
Reputation: 11093
That is because your stepNumber
is static
. That means it's a class variable, thus it will remain 5, as it is the last value which is set (constructor of you last Button
). Removing it will solve the problem.
Let's run through the application:
stepNumber
is 1.stepNumber
is 2.stepNumber
is 3.stepNumber
is 4.stepNumber
is 5.After this it is not set anymore, so it will remain 5. So:
onClick
after that: Log.d()
will output 5Edit: seeing your comment, you probably mean a final
attribute, which cannot be modified and only be set in the constructor. Seeing that you already set it in your constructor, it's perfectly fine to add that to your attribute, making it:
private final int stepNumber;
Edit2: static
members belong to the class instead of a specific instance.
It means that only one instance of a static
field exists even if you create a million instances of the class or you don't create any. It will be shared by all instances.
Upvotes: 4