Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从另一个事件Android Studio获取数据对象_Java_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Java 如何从另一个事件Android Studio获取数据对象

Java 如何从另一个事件Android Studio获取数据对象,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,以下是我的目标活动: refDatabase.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { LatLng newlocation = new LatLng(dataSnapshot.child("latitude").getValue(Double.class),da

以下是我的目标活动:

refDatabase.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        LatLng newlocation = new LatLng(dataSnapshot.child("latitude").getValue(Double.class),dataSnapshot.child("longitude").getValue(Double.class));
        nama = new String(dataSnapshot.child("nama").getValue(String.class));
        kec = new String(dataSnapshot.child("kecamatan").getValue(String.class));
        kab = new String(dataSnapshot.child("kebupaten").getValue(String.class));

        googleMap.addMarker(new MarkerOptions().position(newlocation).title(nama+", "+kec+", "+kab));  
    }
});
如何获取对象
newlocation
,并将其放入此事件中:

tampil.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //
    }
});

您可以使用EventBus Library实现此目的:分三步进行

  • 定义事件(例如locationRetrievedEvent)
  • 注册订户(例如您的活动)
  • 使用EventBust Post()函数发布事件

  • 您可以使用回调来实现这一点。首先,您需要创建一个接口:

    public interface MyCallback {
        void onCallback(LatLng newlocation);
    }
    
    然后,您需要创建一个从数据库中实际获取数据的方法。此方法应如下所示:

    public void readData(MyCallback myCallback) {
        refDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                newlocation = new LatLng(dataSnapshot.child("latitude").getValue(Double.class),dataSnapshot.child("longitude").getValue(Double.class));
                nama = new String(dataSnapshot.child("nama").getValue(String.class));
                kec = new String(dataSnapshot.child("kecamatan").getValue(String.class));
                kab = new String(dataSnapshot.child("kebupaten").getValue(String.class));
    
                googleMap.addMarker(new MarkerOptions().position(newlocation).title(nama+", "+kec+", "+kab));
                myCallback.onCallback(newlocation);
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });
    }
    
    tampil.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            readData(new MyCallback() {
                @Override
                public void onCallback(LatLng newlocation) {
                    //Do what you need to do with newlocation
                }
            });
        }
    });
    
    最后,只需调用
    readData()
    方法,并在
    onClick()
    方法中将
    MyCallback
    接口的实例作为参数传递,如下所示:

    public void readData(MyCallback myCallback) {
        refDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                newlocation = new LatLng(dataSnapshot.child("latitude").getValue(Double.class),dataSnapshot.child("longitude").getValue(Double.class));
                nama = new String(dataSnapshot.child("nama").getValue(String.class));
                kec = new String(dataSnapshot.child("kecamatan").getValue(String.class));
                kab = new String(dataSnapshot.child("kebupaten").getValue(String.class));
    
                googleMap.addMarker(new MarkerOptions().position(newlocation).title(nama+", "+kec+", "+kab));
                myCallback.onCallback(newlocation);
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });
    }
    
    tampil.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            readData(new MyCallback() {
                @Override
                public void onCallback(LatLng newlocation) {
                    //Do what you need to do with newlocation
                }
            });
        }
    });
    

    要了解更多信息,我建议您从这个中查看anwser,并看看这个

    什么是tampil?tampil是一个按钮Alex Mamo解决方案应该可以工作它看起来像是一个过度杀伤力可能是的,它取决于“tampil”单击侦听器的位置,如果click侦听器与refDatabase在同一个类中,我同意您的看法,否则我将使用接口或EventBusNo!如果只有1种情况,您应该使用下面的Mamo解决方案。使用接口作为回调是相当标准的。否则,如果整个项目以EventBus作为整体策略,那么是的!如果数据库事件监听器在另一个类中,这是一个很好的解决方案,为了使事情更安全,我将把click监听器放在回调中。这样,总会有一个按钮,但在解决异步问题之前,按钮并不总是可单击的。一旦异步被解析,那么对象将永远不会为null。而且,我认为op想要的是在单击按钮后对对象执行一些操作,而不是触发数据库请求。这是一个解决方案,即使此代码在同一个类中使用,因为
    onchildaded()
    具有异步行为,当您尝试在onClick()方法中使用
    newlocation
    对象时,数据尚未从数据库加载,因此此对象将始终为
    null
    。请注意,Firebase数据库客户端已经在后台线程中运行了所有网络操作,而没有阻塞主线程。我不明白你为什么要解释Firebase的行为,但我想,谢谢你。然而,你意识到这一点似乎很奇怪,但不要将其应用到解决方案中。如果是这种情况,则应在活动的onCreate内部调用readData,或在片段的onViewCreated内部调用readData。然后回调应该设置click侦听器。这样做会提示出错,用户可以多次单击按钮,而异步调用的按钮尚未返回。
    readData()
    方法应该在需要时调用,在这种情况下,在
    onClick
    方法中。这不会是一个错误,你知道为什么吗?因为使用此回调,我们正在等待数据。所以不会有错误。如果数据未加载,应用程序将不会崩溃,它将等待数据加载。这就是我们使用此回调的原因。我也建议你阅读我的答案。使用一些日志语句或为什么不使用数据库中的真实数据进行一些测试,您将看到行为。因此,您同意用户可以在等待时多次单击按钮,这是我的观点,谢谢