web-dev-qa-db-ja.com

リスナーからデータを取得するためにオブザーバーを実装するにはどうすればよいですか?

MaterialDrawer ライブラリを使用して、アプリの単純なドロワーを作成しています。ライブラリ内のクラスのインスタンスの中には、呼び出されたときに文字列を渡す必要があるものがあります。例はIProfileクラスです。

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

ここで、withName()メソッドは文字列を受け取ります。

MaterialDrawerライブラリが実装されているMainActivityで使用するデータを取得するために使用する予定のクラス_MyObservable.Java_(Observableを拡張)クラスを作成しました。このクラスには、Firebaseデータベースから必要なもののリスナーを持つメソッドimplementData()があります。

これはどのように見えるかです:

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

次に、changeUsername()メソッドを使用してユーザー名の変更をオブザーバーに通知します。

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

        setChanged();
        notifyObservers(username);
    }
_

MyObservableクラスには、オブザーバーが更新されるたびに呼び出されるupdate()メソッドを使用してMyObserverを実装するObserverクラスがあります。今のところ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("[email protected]")
                .withIcon(R.drawable.avatar2);
    }

    ...

}
_

MainActivityで使用するデータを取得しようとして、リスナーで発生しているイベントに「react」を試みるのに何時間も費やしましたが、そうではありませんObservable/Observerパターンを適切に使用していることを確認してください。これは、データを取得するためのFirebaseによる非同期イベントであるため、オブザーバーを使用することがこれを行うための最良の方法です。

appDrawer()メソッドは私のアクティビティのonCreate()で呼び出されます。

オブザーバーを使用してリスナーからデータを取得し、他の場所で使用できるようにするにはどうすればよいですか?

8
Feyisayo Sonubi

あなたのデザインでは、実際に何が起こっているのかわかりません。クラスにListenerという名前を付けてから、それをObservableにするのは、直感に反しているようです。リスナーは聞いたり観察したりします。それでも、ListenerObserverという別のクラスがあるように思われるので、少し迷っていますが、パターンを正しく実装したかどうかわからないようです。例を挙げて説明できます。

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

updateメソッドは、監視しているオブジェクトと、notifyObservers()に渡した引数(オブザーバーと共有するデータ)を提供します。このようにした場合は、期待どおりの動作が得られるはずです。

ご覧のとおり、データはオブザーバブルの外側または内側にあるオブザーバーに送信できます。あなたがそれを実行すると、出力は...

こんにちはオブザーバブル

15
ChiefTwoPencils