2016-01-29 18 views
5

Używam biblioteki MaterialDrawer do utworzenia prostej szuflady dla mojej aplikacji. Niektóre instancje klas w bibliotece wymagają podania ciągu do nich po wywołaniu. Przykładem jest klasa IProfile:Jak zaimplementować obserwatora, aby uzyskać dane od detektora?

IProfile profile = new ProfileDrawerItem().withName("John Doe");

gdzie metoda withName() trwa w ciąg.

Utworzono klasę klasy MyObservable.java (rozszerzenie Observable), której zamierzam użyć, aby pobrać dane do mojego MainActivity z biblioteką MaterialDrawer. W tej klasie mam metodę implementData(), która ma mojego słuchacza dla potrzebnej mi bazy danych firebase.

To jak to wygląda:

public class MyObservable extends Observable { 

    // Attach our firebase reference... 
    Firebase userRef = new Firebase("https://myApp.firebaseio.com/users"); 
    AuthData authData; 

    public String username = ""; 
    public String email = ""; 


    public void changeUsername(String username) { 
     this.username = username; 

     setChanged(); 
     notifyObservers(username); 
    } 


    public void implementData(){ 
     // Get the authentication data of our user from the reference. 
     authData = userRef.getAuth(); 

     // This is the listener I have to get the data from. 
     userRef.child(authData.getUid()).addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot snapshot) { 

       UserSchema user = snapshot.getValue(UserSchema.class); 
       // This guy needs to be used in the MainActivity appDrawer() method 
       String userName = user.getName(); 
      } 

      @Override 
      public void onCancelled(FirebaseError firebaseError) { 

      } 
     }); 

    } 
} 

class MyObserver implements Observer { 

    public void update(Observable observable, Object data) { 
     // For now I just print it out to System.out 
     System.out.println("Username:" + data); 
    } 
} 

Potem powiadomić moich obserwatorów o zmianie nazwy użytkownika ze sposobem changeUsername():

public void changeUsername(String username) { 
     this.username = username; 

     setChanged(); 
     notifyObservers(username); 
    } 

W MyObservable klasie, mam klasę MyObserver że implementuje Observer z metodą update() wywoływaną za każdym razem, gdy obserwator został zaktualizowany. W metodzie update() na razie wydrukuję tylko użytkownika username użytkownika, aby upewnić się, że coś się dzieje.

To gdzie muszę dane od obserwatora (w główną działalność):

public class MainActivity extends AppCompatActivity { 
    ... 

    public void appDrawer(){ 

     IProfile profile = new ProfileDrawerItem() 

       // I need the user's data here 
       .withName("Test") 
       .withEmail("[email protected]") 
       .withIcon(R.drawable.avatar2); 
    } 

    ... 

} 

Spędziłem godzin próbując „reagować” do wydarzeń dziejących się w słuchacza próbując odzyskać dane do użycia w MainActivity, ale nie jestem pewien, czy używam wzoru Observable/Observer prawidłowo, również dlatego, że jest to asynchroniczne wydarzenie Firebase, które pozwala uzyskać dane, przy użyciu Observera jest to najlepszy sposób na zrobienie tego.

Metoda appDrawer() jest wywoływana w mojej działalności onCreate().

W jaki sposób mogę odzyskać dane z odbiornika za pomocą obserwatora, aby móc go używać w innym miejscu?

Odpowiedz

13

Nie mogę powiedzieć, według twojego projektu, co się naprawdę dzieje. Nazywanie klasy Listener sprawia, że ​​wydaje się ona być niezrozumiała. Słuchacz słucha lub obserwuje. Jednak brzmi to tak, jakbyś miał inną klasę w Listener, która jest Observer, więc jestem trochę zagubiony, ale wydajesz się niepewny, czy poprawnie zaimplementowałeś wzorzec. Że mogę wyjaśnić przykład.

public class MyObserver implements Observer { 
    @Override 
    public void update(Observable o, Object arg) { 
     System.out.println(arg + " " + ((MyObservable)o).name); 
    } 
} 

public class MyObservable extends Observable { 

    public String name = "Observable"; 

    public void changeMe(String word) { 
     setChanged(); 
     notifyObservers(word); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     MyObservable myObservable = new MyObservable(); 
     myObservable.addObserver(new MyObserver()); 
     myObservable.changeMe("Hello"); 
    } 
} 

Sposób update daje obiekt, który obserwujesz, jak również argumenty (dane, które mają wspólne z obserwatorem), które przeszły do ​​notifyObservers(). Jeśli zrobiłeś to tak, to powinieneś uzyskać zachowanie, którego się spodziewasz.

Jak widać dane mogą być wysyłane do obserwatorów na zewnątrz lub wewnątrz obserwowalnego obiektu. Po uruchomieniu wyjście jest ...

Witam zaobserwowania

+0

'notifyObservers (String)' powinna być wywołana z 'changeme()'. – cybergen

+1

@cybergen, "should be" prawdopodobnie jest dla mnie trochę restrykcyjne. Jest publiczny, więc jest celowo wyeksponowany. Powiedziałbym, że w ogólnym przypadku wywołanie 'notifyObservers' w każdej metodzie, która zmienia stan, może być nadmierne. Widzę jednak twój punkt widzenia. W przypadku PO nie ma to znaczenia, ponieważ istnieje tylko jedno powiadomienie. Zmienię to dla twojej przyjemności oglądania, więc lepiej pasuje do kodu OP. – ChiefTwoPencils

+0

Oh wow, dziękuję bardzo, więc mogę mieć metodę 'changeMe' zwrócić ciąg, który jest aktualizowany zamiast i obserwatorzy nie muszą być dodawane wewnątrz obserwowalne tak? –

Powiązane problemy