Reputation: 215
I alter a variable on different button clicks, (i.e. inside the onclick listener for multiple buttons) and I have a textview that is suppose to show this variable, but remains outside the listener code.
The textview doesnt update the variable, so I am thinking i possibly need an 'onclick' handler version for variables.
How would I go about doing this?
Upvotes: 6
Views: 14342
Reputation: 460
In C# there is an easy way to trigger some action once a variable changes so it is in Java. Java afaik do not support operators overloading, but this feature is not necessary. When it comes to classes (object) oriented programming, just create your special type out of any standard type. A new class will extend the features od any type (int, long, string, etc.). Define, for example your own "SET" and/or "GET" methods and just use these instead of standard "=" or get value/ponter as left operand.
Example:
public class myINT
{
public int Value;
public void SET(int v) {Value = v; // PLUS additional ACTION }
public int GET(int v) {return Value ;}
public void ADD(int v) {Value += v; // PLUS additional ACTION }
public void SUB(int v) {Value -= v; // PLUS additional ACTION }
}
Upvotes: -1
Reputation: 10358
There is no way in Java to be notified when a variable or class field changes. What you need to do is to implement a simple wrapper class for your int so that clients can register for callbacks whenever the value changes. This class might look something like this:
package com.example.android;
/**
* A store of an int value. You can register a listener that will be notified
* when the value changes.
*/
public class IntValueStore {
/**
* The current value.
*/
int mValue;
/**
* The listener (you might want turn this into an array to support many
* listeners)
*/
private IntValueStoreListener mListener;
/**
* Construct a the int store.
*
* @param initialValue The initial value.
*/
public IntValueStore(int initialValue) {
mValue = initialValue;
}
/**
* Sets a listener on the store. The listener will be modified when the
* value changes.
*
* @param listener The {@link IntValueStoreListener}.
*/
public void setListener(IntValueStoreListener listener) {
mListener = listener;
}
/**
* Set a new int value.
*
* @param newValue The new value.
*/
public void setValue(int newValue) {
mValue = newValue;
if (mListener != null) {
mListener.onValueChanged(mValue);
}
}
/**
* Get the current value.
*
* @return The current int value.
*/
public int getValue() {
return mValue;
}
/**
* Callbacks by {@link IntValueModel}.
*/
public static interface IntValueStoreListener {
/**
* Called when the value of the int changes.
*
* @param newValue The new value.
*/
void onValueChanged(int newValue);
}
}
Now you need to have some class that implements the IntValueStoreListener interface. You could let that be the Activity
, which would then keep track of a TextView
to update. I would implement a trivial custom TextView
instead, like this:
package com.example.android;
import com.example.android.IntValueStore.IntValueStoreListener;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
public class IntTextView extends TextView implements IntValueStoreListener{
public IntTextView(Context context) {
super(context);
}
public IntTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void onValueChanged(int newValue) {
// The int got a new value! Update the text
setText(String.valueOf(newValue));
}
}
You can now setup your layout XML. For example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_increment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Increment" />
<Button
android:id="@+id/btn_double"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Double" />
<com.example.android.IntTextView
android:id="@+id/text_current_value"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
An activity that does the necessary setup would look like this:
package com.example.android;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class IntValueStoreActivity extends Activity {
private IntValueStore mIntValueModel = new IntValueStore(1);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the text view with the initial value
IntTextView intTextView = (IntTextView)findViewById(R.id.text_current_value);
intTextView.setText(String.valueOf(mIntValueModel.getValue()));
// Setup the text view as a listener so it gets updated whenever the int
// value changes
mIntValueModel.setListener(intTextView);
// Setup an OnClickListener that will increment the int value by 1. The
// TextView will be automatically updated since it is setup as a
// listener to the int value store
findViewById(R.id.btn_increment).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mIntValueModel.setValue(mIntValueModel.getValue() + 1);
}
});
// Setup an OnClickListener that will double the int value. The TextView
// will be automatically updated since it is setup as a listener to the
// int value store
findViewById(R.id.btn_double).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mIntValueModel.setValue(mIntValueModel.getValue() * 2);
}
});
}
}
This will give you the following UI:
Whenever you click any of the buttons, the TextView
will almost magically update the value it displays, even though none of the OnClickListeners have any code to touch the TextView
!
This is actually a common pattern in programming called Model-view-controller. In the sample code above, the Model is IntValueStore
and the View is IntTextView
and there is no Controller.
Upvotes: 19