it-swarm.com.de

Wie erstellt man einen Änderungslistener für eine Variable?

Nehmen wir an, ich habe einige Variablen mit der Anweisungint someVariable; definiert. Während der Code ausgeführt wird, ändert sich der Wert der Variablen.

Wie kann ich die Änderungen in dieser Variablen verfolgen? Wie könnte ich einen Listener implementieren, der sich wie onSomeVariableChangedListener verhält? 

Ich muss auch wissen, wann eine andere Methode auf einer Seite ausgeführt wurde, damit ich einen Listener in einer anderen Klasse einstellen kann.

37
Sinigami

Dies ist einer der vielen Gründe, um Variablen hinter setter/getter - Paaren zu verbergen. Dann können Sie im Setter Ihren Listener darüber informieren, dass diese Variable entsprechend geändert wurde. Wie die anderen kommentiert haben, gibt es keine Möglichkeit, genau das zu tun, was Sie wollen, Sie müssen es selbst implementieren.

Alternativ zeigt Benjamin ein interessantes Muster an, das als Decorator-Muster bezeichnet wird. Dies kann für Sie nützlich sein, wenn der betreffende Code nicht geändert werden kann. Mehr Infos findest du bei Wikipedia

Die Idee ist, einen kompatiblen Wrapper um ein Objekt zu erstellen. Nehmen wir an, Ihr Objekt ist vom Typ MyClass.

class MyClass{
   publc void doFunc(){...}
}

class MyLoggedClass extends MyClass{
    MyClass myObject;

    publc void doFunc(){
        //Log doFunc Call

       myObject.doFunc();

    }
}

anstatt 

MyClass object = new MyClass();

Du würdest verwenden 

MyClass object = new MyLoggedClass(new MyClass());

Jetzt wird der Rest des Codes normal verwendet, mit der Ausnahme, dass jeder Funktionsaufruf protokolliert oder benachrichtigt wird usw.

Wie Sie in Wikipedia sehen werden, geschieht dies normalerweise über eine Schnittstelle, von der die betreffende Klasse erbt. In Ihrem Fall ist dies jedoch möglicherweise nicht möglich.

28
Karthik T

Java bietet Ihnen eine einfache Observer-Musterimplementierung für diese Art von Dingen, aber Sie müssen Ihre beobachtete Variable innerhalb einer Methode festlegen, die Listener-Benachrichtigungen verwaltet. Wenn Sie Observable nicht erweitern können, können Sie entweder Komposition verwenden (dh Sie haben eine Observable-Instanz in Ihrer Klasse, um Benachrichtigungen zu verwalten), oder Sie können Java.util.Observable ansehen, um eine Vorstellung davon zu erhalten, wie Sie Ihre eigenen Rollen erstellen können Ausführung.

Flux.Java

import Java.util.Observable;

public class Flux extends Observable {
  private int someVariable = 0;

  public void setSomeVariable(int someVariable) {
    synchronized (this) {
      this.someVariable = someVariable;
    }
    setChanged();
    notifyObservers();
  }

  public synchronized int getSomeVariable() {
    return someVariable;
  }
}

Heraclitus.Java

import Java.util.Observable;
import Java.util.Observer;

public class Heraclitus implements Observer {
  public void observe(Observable o) {
    o.addObserver(this);
  }

  @Override
  public void update(Observable o, Object arg) {
    int someVariable = ((Flux) o).getSomeVariable();
    System.out.println("All is flux!  Some variable is now " + someVariable);
  }
}
35
Kevin Condon

Ich glaube, Sie müssen Observer Pattern implementieren.

3

Sie können View Model verwenden. Erstellen Sie zuerst eine Klasse, die das Ansichtsmodell erweitert. Ich habe mein NameViewModel angerufen.

import Android.Arch.lifecycle.MutableLiveData;
import Android.Arch.lifecycle.ViewModel;

public class NameViewModel extends ViewModel {
private MutableLiveData<String> currentName;

public MutableLiveData<String> getCurrentName(){
        if(currentName == null){
            currentName = new MutableLiveData<>();
        }
        return currentrName;
    }
}

dann definieren Sie in der Aktivität, dass die Variablenwertänderung zuerst eine Instanz Ihrer NameViewModel-Klasse definiert:

private NameViewModel mNameViewModel;

verwenden Sie dann in onCreate dieses Code-Snippet 

mNameViewModel = ViewModelProvider.of(this).get(NameViewModel.class)
mNameViewModel.getCurrentName().observe(this, new Observer<String>() {
    @Override
    public void onChanged(@Nullable String name) {
        //do what you want when the varriable change.
    }
});

wenn Sie den Wert von name ändern möchten, können Sie dieses Code-Snippet verwenden:

mNameViewModel.getCurrentName().postValue(String newName);

Ich verwende postValue (), da ich die Variable vom Worker-Thread aktualisieren möchte. Wenn Sie sich im UI-Thread befinden, sollten Sie setValue () ..__ verwenden. Jetzt wird die Benutzeroberfläche jedes Mal aktualisiert, wenn die Variable geändert wird.

1

In Java gibt es keine integrierte Möglichkeit, eine Benachrichtigung zu erhalten, wenn sich der Wert einer beliebigen Variablen ändert oder eine Methode aufgerufen wurde.

1
Jesper