2016-01-29 45 views
5

Tôi đang sử dụng thư viện MaterialDrawer để tạo ngăn kéo đơn giản cho ứng dụng của mình, một số phiên bản của các lớp trong thư viện cần chuỗi được chuyển vào chúng khi được gọi. Một ví dụ là lớp IProfile:Làm cách nào để triển khai Trình theo dõi để lấy dữ liệu từ người nghe?

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

nơi phương pháp withName() mất trong một chuỗi.

Tôi đã tạo lớp học MyObservable.java (mở rộng có thể quan sát) mà tôi dự định sử dụng để lấy dữ liệu được sử dụng trong MainActivity của mình có thư viện MaterialDrawer được triển khai. Trong lớp này, tôi có phương thức implementData() có trình nghe của tôi cho những gì tôi cần từ cơ sở dữ liệu Firebase của mình.

Đây là những gì nó trông giống như:

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); 
    } 
} 

Sau đó, tôi thông báo cho các quan sát viên của tôi về sự thay đổi tên người dùng với các changeUsername() phương pháp:

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

     setChanged(); 
     notifyObservers(username); 
    } 

Trong lớp MyObservable, tôi có một lớp MyObserver rằng triển khai Observer bằng phương thức update() được gọi mỗi khi người quan sát được cập nhật. Trong phương thức update() hiện tại, tôi chỉ in ra username của người dùng để đảm bảo điều gì đó thực sự đang diễn ra.

Đây là nơi tôi cần dữ liệu từ các quan sát viên (Trong MainActivity):

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); 
    } 

    ... 

} 

Tôi đã dành giờ cố gắng để 'phản ứng' đến các sự kiện xảy ra ở người nghe bằng cách cố gắng để lấy dữ liệu được sử dụng trong MainActivity của tôi nhưng tôi không chắc chắn rằng tôi đang sử dụng mẫu Observable/Observer đúng cách, vì đây là sự kiện không đồng bộ của Firebase để lấy dữ liệu, sử dụng Observer là cách tốt nhất để thực hiện việc này.

Phương thức appDrawer() được gọi trong Hoạt động của tôi onCreate().

Làm cách nào để truy xuất dữ liệu từ Trình xử lý với Trình quan sát, vì vậy tôi có thể sử dụng nó ở nơi khác?

Trả lời

13

Tôi không thể nói bằng thiết kế của bạn những gì thực sự đang diễn ra. Đặt tên cho một lớp là Listener rồi làm cho nó Observable có vẻ phản trực giác. Người nghe lắng nghe hoặc quan sát. Tuy nhiên, có vẻ như bạn có một lớp học khác trong số Listener đó là một số Observer vì vậy tôi bị mất một chút nhưng bạn dường như không chắc chắn liệu bạn đã triển khai đúng mẫu chưa. Điều đó tôi có thể làm sáng tỏ bằng một ví dụ.

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"); 
    } 
} 

Phương pháp update cung cấp cho bạn các đối tượng bạn đang quan sát cũng như các đối số (các dữ liệu mà bạn muốn chia sẻ với các quan sát viên), bạn truyền vào notifyObservers(). Nếu bạn đã thực hiện nó như thế này thì bạn sẽ nhận được hành vi mà bạn mong đợi.

Như bạn có thể thấy dữ liệu có thể được gửi đến các nhà quan sát bên ngoài hoặc bên trong có thể quan sát được. Khi bạn chạy nó, đầu ra là ...

Xin chào Quan sát

+0

'notifyObservers (String) 'nên được gọi là từ' changeMe() '. – cybergen

+1

@cybergen, "nên" có lẽ là một chút hạn chế đối với tôi. Đó là công khai vì vậy nó cố ý tiếp xúc. Tôi sẽ nói trong trường hợp chung gọi 'notifyObservers' trong mọi phương thức mà thay đổi trạng thái có thể là quá mức. Mặc dù vậy, tôi vân nhìn thấy điểm của bạn. Trong trường hợp của OP nó không quan trọng vì chỉ có một thông báo. Tôi sẽ chỉnh sửa nó cho niềm vui của bạn xem và vì vậy nó phù hợp với mã của OP tốt hơn. – ChiefTwoPencils

+0

Oh wow, cảm ơn bạn rất nhiều, vì vậy tôi có thể có phương pháp 'changeMe' trả về chuỗi đang được cập nhật thay vào đó và các nhà quan sát không cần phải thêm vào bên trong có thể quan sát được? –

Các vấn đề liên quan