如何实现Observer以从侦听器获取数据?

Fey*_*ubi 7 java android observable observer-pattern firebase

我正在使用MaterialDrawer库为我的应用程序创建一个简单的抽屉,库中的一些类实例需要在调用时传递给它们的字符串.一个例子是这个IProfile类:

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

其中withName()方法接受的字符串.

我已经创建了一个类MyObservable.java(扩展Observable)类,我打算用它来获取要在我MainActivity实现MaterialDrawer库的数据.在这个类中,我有一个方法implementData(),它可以从我的firebase数据库中获取我需要的内容.

这就是它的样子:

    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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我通过方法通知我的观察者用户名更改changeUsername():

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

        setChanged();
        notifyObservers(username);
    }
Run Code Online (Sandbox Code Playgroud)

在MyObservable类中,我有一个MyObserver类,无论何时更新观察者,都会调用Observerupdate()方法.在update()现在的方法中,我只打印出username用户的内容以确保实际发生了什么.

这是我需要来自观察者的数据(在MainActivity中):

public class MainActivity extends AppCompatActivity {
    ...

    public void appDrawer(){

        IProfile profile = new ProfileDrawerItem()

                // I need the user's data here
                .withName("Test")
                .withEmail("test@test.com")
                .withIcon(R.drawable.avatar2);
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

我花了几个小时试图通过尝试检索要在我的MainActivity中使用的数据来对发生在侦听器中的事件做出 " 反应 ",但我不确定我是否正确使用了Observable/Observer模式,因为这是一个异步Firebase获取数据的事件,使用Observer是最好的方法.

appDrawer()方法在我的Activity中调用onCreate().

如何使用Observer从Listener中检索数据,以便在其他地方使用它?

Chi*_*ils 15

我不知道你的设计究竟发生了什么.命名一个类Listener然后使它Observable看起来反直觉.听众倾听或观察.然而,这听起来像你在另一个类Listener这是一个Observer,所以我有点失落,但你似乎不确定,如果您正确实施的模式.我可以用一个例子清理一下.

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

update方法为您提供了您正在观察的对象以及您传入的参数(您希望与观察者共享的数据)notifyObservers().如果你这样做了,那么你应该得到你期望的行为.

如您所见,可以将数据发送到可观察对象外部或内部的观察者.当你运行它时输出是......

你好Observable