I need to pass a value from my main Activity to a custom View.
In the main activity I have a SensorEventListener so I'm continuosly listening to the light sensor. In the onSensorChanged() method I read the value, and I need to send this value every time it changes to my custom View.
I don't know which is the best way to achive this.
UPDATE --
Method refered to SensorEventListener on main activity:
#Override
public void onSensorChanged(SensorEvent event) {
float lumnes = event.values[0];
GaugeView.setHandTarget(lumnes);
}
Method I have to send values to in custom view:
public void setHandTarget(float temperature) {
if (temperature < minDegrees) {
temperature = minDegrees;
} else if (temperature > maxDegrees) {
temperature = maxDegrees;
}
handTarget = temperature;
handInitialized = true;
invalidate();
}
I cannot use static references cause then I cannot call invalidate()
You could do this:
public CustomView extends View {
...
private float[] values; //this
//setter
public void setValues(float[] values) {
this.values = values;
}
}
public class MyActivity extends Activity implements SensorEventListener {
private CustomView mCustomView;
...
#Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
mCustomView.setValues(values); //pass the collected values to the view via setter
}
}
Without seeing any of your code, the best advice I can give is to create a property in your view, and make it accessible from your Main Activity class. In your method that is checking the sensor, you can simply set the custom View's property that you created to be the value. Not so much passing the value as directly accessing it.
Assuming your value is a float, add something like this to your Custom view class:
public float sensorValue;
Access it from the sensor event listener like this:
CustomView.sensorValue = sensorValue;
Related
In Android, how do I take an action whenever a variable changes?
So I want to implement a listener for an object I created. What I want it to do is execute a block of code when its value changes from false to true.
As I am following this thread, I can't understand where the person wants us to implement the last block of code containing the logic for the listener.
Could someone, hopefully, guide me in the right direction?
(This question is being asked here as I don't have enough rep. points)
That last bit of example code triggers the listener, so it basically needs to be run whenever the "event" occurs. In this case the "event" is whenever (wherever in the code) the value of the variable changes.
If you have a setter and that is the only place the value changes, that is where you'd put it. If you are changing the value in multiple places throughout your code, I would make a new private method (call it signalChanged), put your code there, and then call it immediately after the variable assignment in the cases you want the listener to fire.
Here's an example (some code borrowed from linked answer, haven't checked that it compiles).
public class MyObj
{
public MyObj(int value)
{
setValue(value);
}
private int myValue;
public int getValue() { return myValue; }
public void setValue( int value )
{
if (value != myValue)
{
myValue = value;
signalChanged();
}
}
public interface VariableChangeListener
{
public void onVariableChanged(Object... variableThatHasChanged);
}
private VariableChangeListener variableChangeListener;
public void setVariableChangeListener(VariableChangeListener variableChangeListener)
{
this.variableChangeListener = variableChangeListener;
}
private void signalChanged()
{
if (variableChangeListener != null)
variableChangeListener.onVariableChanged(myValue);
}
}
you have to create a callback interface
here is a good about custom listener tutorial
here is a sample
public class MyObj {
VariableChanger onVariableChanged ;
public void setOnVariableChanged(VariableChanger onVariableChanged) {
this.onVariableChanged = onVariableChanged;
}
void log(){
boolean changed = false;
onVariableChanged.onVariableChanged();
//this will call it
}
interface VariableChanger{
void onVariableChanged();
}
}
class logic {
MyObj mo = new MyObj();
void main(){
mo.setOnVariableChanged(new MyObj.VariableChanger() {
#Override
public void onVariableChanged() {
//do your action
}
});
}
}
In Android, like any language, most developper uses logic comparisons to check values (if, else, switch, =, !=, >, <, etc) or Event (signal)
What kind of listener do you want to implement?
I have a variable in my class , I want when that variable changed , I do an action in another class .
in fact I want a listener for changing variable in android (my variable may change every minute)
public class Connect {
public static boolean myBoolean;
//some actions do and myBoolean change
}
public class Selection extends Activity implements OnMenuItemClickListener{
//I want a thing like listener here ,when myboolean changed I do an action (myboolean may change every minute)
}
It's not possible directly. However, you can make your field private, add getters and setters, and create a method of adding listeners (this is called the Observer pattern):
interface ConnectionBooleanChangedListener {
public void OnMyBooleanChanged();
}
public class Connect {
private static boolean myBoolean;
private static List<ConnectionBooleanChangedListener> listeners = new ArrayList<ConnectionBooleanChangedListener>();
public static boolean getMyBoolean() { return myBoolean; }
public static void setMyBoolean(boolean value) {
myBoolean = value;
for (ConnectionBooleanChangedListener l : listeners) {
l.OnMyBooleanChanged();
}
}
public static void addMyBooleanListener(ConnectionBooleanChangedListener l) {
listeners.add(l);
}
}
Then, wherever you want to listen to changes of the boolean, you can register a listener:
Connect.addMyBooleanListener(new ConnectionBooleanChangedListener() {
#Override
public void OnMyBooleanChanged() {
// do something
}
});
Adding a method to remove listeners is left as an exercise. Obviously, for this to work, you need to make sure that myBoolean is only changed via setMyBoolean, even inside of Connect.
This question has nothing to with debugging or in other words I'm not trying to monitor the value of a certain variable to verify if the code is running correctly. I have 6 buttons that can be enabled depending on a variable which we will call X. Each button has a different threshold of what X needs to be in order to enable that button. For example, button1 is enabled if X is at least 50, button2 if X is at least 165, etc. I can have an asynctask to poll variable X and enable or disable the buttons but is there a better way?
Add your variable to a class like so:
public class example {
private int X;
public int getX() { return X; }
public void setX(int x) {
X = x;
// When X is set notify your watchers
}
}
Next create an interface like so:
public interface VariableChangeWatcher {
public void variableChanged(int value);
}
If you make your class use this interface you can add watchers or listeners to know when the value of X has changed outside the class:
public class example {
VariableChangeWatcher watcher;
private int X;
public int getX() { return X; }
public void setX(int x) {
X = x;
// When X is set notify your watchers
if (watcher != null)
watcher.variableChanged(x);
}
}
Then in any class that uses example you can simply listen in to the interface to know when the value of X has changed:
public class exampleListener implements VariableChangeWatcher
{
public exampleListener() {
example e = new example();
}
#Override
public void variableChanged(int value) {
// Gets alerted when the X value inside our e variable has changed
}
}
Use encapsulation. Do not make x a variable. Make it a class, with a value inside it. Put a setter function on it. Then whenever the setter function is called, have it set the value and enable/disable all the proper buttons. This way you can't forget to do it anywhere- the only way to set it is via the setter method.
I've created some getters setters in my Application class as so:
public class myApp extends Application{
//"Global" variables
private Boolean musicEnabled = true; //Music on or off?
private Boolean soundEnabled = true; //Sound effects on or off?
#Override
public void onCreate() {
// TODO Auto-generated method stub
musicEnabled = true; //Default value for music
soundEnabled = true; //Default value for sound effects
super.onCreate();
}
//Getter and setter for musicEnabled
public Boolean getMusicOption(){
return musicEnabled; //Getter
}
public void setMusicOption(Boolean value){ //Setter
musicEnabled = value;
}
//Getter and setter for soundEnabled
public Boolean getSoundOption(){
return soundEnabled;
}
public void setMusicOptions(Boolean value){
soundEnabled = value;
}
}
I then get the values in my Activity class as so:
myApp myAppSettings = (myApp)getApplicationContext();
musicEnabled = myAppSettings.getMusicOption();
soundEnabled = myAppSettings.getSoundOption();
This is fine but what I can't figure out is how I can get to them and use them from my corresponding surfaceView class? i.e. the class that starts:
public class mySView extends SurfaceView implements
SurfaceHolder.Callback {
The only way I've manages to do this so far is pass them into my surfaceview class by creating a method like:
public void initialise(Boolean Sound, Boolean Music){
}
And then passing these in from my Activity class like so:
myView.initialise(musicEnabled, soundEnabled).
This works, however it seems a bit messy, I mean I am going to need to use the setters from my 'myView' class to set these value so........ is there anyway I can access them directly from my 'myView' class or do I have to do this from the Activity class?
Thanks all
You can create some method, e.g. init() and call it from all of constructors of your mySView.
In init method you can do the same, as in the Activity:
private void init() {
myApp myAppSettings = (myApp)getContext().getApplicationContext();
musicEnabled = myAppSettings.getMusicOption();
soundEnabled = myAppSettings.getSoundOption();
}
You should just be able to call getContext().getApplicationContext() from inside your custom SurfaceView, and typecast it like you would in your above example. See View.getContext().
Another option would be to save your settings in the SharedPreferences which is accessable anywhere in the App where you have the Context.
This way any changes from the last use of your App will automatically be persisted as can be loaded during next launch without having to return the values to default every launch.
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
I am working on a game involving measuring accelerometer values and manipulating my character's position based on those values. I am only working with the X axis. I initiate my accelerometer manager in my main activity, but I need to use these values in another class. Obviously these values are constantly changing. How could I pass these values to my GameView class?
You can save them as static members of your activity, or pass them to GameView class each time there's a change in them (new value)
If you've used a sensorlistener you might think about moving that logic to the GameView class. Not totally sure without looking at your code though. Do you have any samples?
Why not do it the Android way? :)
When you implement a touch listener, you do something set like this:
myView.setOnTouchlistener(this):
This tells the view to call you back when it's touched. Here's how to do your own:
Define an interface and use a callback to let the class know that a value has changed.
public interface AccelerometerUpdateListener {
void onUpdate(int arg1, string arg2); ..<----add arguments you want to pass back
}
In your Activity:
public class MainActivity extends Activity implements AccelerometerUpdateListener {
ArrayList<AccelerometerUpdateListener > listeners = new ArrayList<AccelerometerUpdateListener >();
...
#Override
public void onCreate(Bundle savedInstanceState)
{
...
myGameClass.setResponseReceivedistener(this);
...
}
public void setUpdateListener(AccelerometerUpdateListener listener){
if (!listeners.contains(listener){
listeners.add(listener);
}
}
public void removeUpdateListener(AccelerometerUpdateListener listener){
if (listeners.contains(listener){
listeners.remove(listener);
}
}
When you update the values
for (AccelerometerUpdateListener listener:listeners){
listener.onUpdate(arg1, arg2);
}
In your receiving class:
public class MyGameClass implements AccelerometerUpdateListener {
...
#Override
public void onUpdate(int arg1, string arg2){
// do whatever you need to do
}
All from memory so please excuse typos.