在 android 中从 Firebase 实时数据库检索 ListView 上的数据无法正常工作
retrieve data on ListView from Firebase Realtime Database in android not working
我试图从 firebase 动态检索数据并将它们显示在页面上,但是当我这样做时没有错误,但注意到屏幕上出现的只是一个空屏幕(见下图)
This is the output when I click on the page
有人可以帮我吗?
这是我的 Firebase
数据库结构。
这是我的 java 代码:
package com.example.atheer.booklyv1;
import android.app.ListActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class orgServices extends AppCompatActivity {
ListView ListView;
FirebaseDatabase database;
DatabaseReference ref;
ArrayList<Service> list;
ArrayAdapter<Service> adapter;
Service ser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_org_services);
ser = new Service();
ListView = (ListView) findViewById(R.id.ListView);
database = FirebaseDatabase.getInstance();
ref =database.getReference().child("client");
list = new ArrayList<>();
adapter = new ArrayAdapter<Service>(this, R.layout.service_info,R.id.serviceInfo,list);
ref.addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
for(DataSnapshot ds: dataSnapshot.getChildren())
{
if (dataSnapshot.hasChild("services")){
ser= ds.getValue(Service.class);
list.add(ser);}
}
ListView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError){
}
});
}
}
这是 ListView 的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".orgServices">
<ListView
android:id="@+id/ListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</android.support.constraint.ConstraintLayout>
这是 ListView 中每个元素的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/serviceInfo"
android:textSize="30sp"
android:text="Name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
我定制了适配器 class:
适配器 class :
package com.example.atheer.booklyv1;
import android.support.v7.app.AppCompatActivity;
public class Service extends AppCompatActivity {
private int price;
private String name;
private int totalpoint;
private int rating;
public Service(){
}
public Service (String name){
this.name=name;
}
public Service (String name, int price , int totalpoint , int rating ){
this.name=name;
this.price=price;
this.totalpoint=totalpoint;
this.rating=rating;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTotalpoint() {
return totalpoint;
}
public void setTotalpoint(int totalpoint) {
this.totalpoint = totalpoint;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
}
这些消息来自 运行 部分:
V/FA: Recording user engagement, ms: 748436
V/FA: Connecting to remote service
V/FA: Activity paused, time: 1449333
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=748436, firebase_screen_class(_sc)=Service, firebase_screen_id(_si)=-4092656992746331939}]
I/atheer.booklyv: Waiting for a blocking GC ProfileSaver
V/FA: Connection attempt already in progress
V/FA: Connection attempt already in progress
Activity resumed, time: 1449354
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=Service, firebase_previous_id(_pi)=-4092656992746331939, firebase_screen_class(_sc)=Mynavigation, firebase_screen_id(_si)=-4092656992746331940}]
I/atheer.booklyv: WaitForGcToComplete blocked ProfileSaver on ProfileSaver for 62.701ms
V/FA: Connection attempt already in progress
D/EGL_emulation: eglMakeCurrent: 0xebd05420: ver 3 0 (tinfo 0xebd033e0)
D/FA: Connected to remote service
V/FA: Processing queued up service tasks: 4
V/FA: Recording user engagement, ms: 3384
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@6a2bdcc
V/FA: Activity paused, time: 1452737
V/FA: onActivityCreated
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=3384, firebase_screen_class(_sc)=Mynavigation, firebase_screen_id(_si)=-4092656992746331940}]
V/FA: Activity resumed, time: 1452998
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=Mynavigation, firebase_previous_id(_pi)=-4092656992746331940, firebase_screen_class(_sc)=Service, firebase_screen_id(_si)=-4092656992746331938}]
D/EGL_emulation: eglMakeCurrent: 0xebd05420: ver 3 0 (tinfo 0xebd033e0)
问题出在使用 dataSnapshot
检索时。您正在做的是,如果您找到名称为 services
的 child,您将尝试从 Services.class
.[=22= 中的当前 dataSnapshot
获取数据]
您应该做的是,在您选择的 child 上设置正确的 databaseReference
。
因此,您可以在 if
语句中试试这个,而不是您用来检索的代码:
String name = dataSnapshot.child("name").getValue(String.class);
String name = dataSnapshot.child("price").getValue(Integer.class);
String name = dataSnapshot.child("rating").getValue(Integer.class);
String name = dataSnapshot.child("totalpoint").getValue(Integer.class);
如果你想在不设置不同的 getValue()
语句的情况下获取所有值,你可以使用 map
来实现。这可以帮助您同时从数据库中更新和检索值。
您可以参考以下 link 了解更多关于使用 map
从 FirebaseDatabase
检索数据的信息。
要解决这个问题,只需移动以下代码行:
adapter = new ArrayAdapter<Service>(this, R.layout.service_info,R.id.serviceInfo,list);
之前:
ListView.setAdapter(adapter);
当您设置适配器时,您的列表是空的,这就是为什么屏幕是空的。
我试图从 firebase 动态检索数据并将它们显示在页面上,但是当我这样做时没有错误,但注意到屏幕上出现的只是一个空屏幕(见下图)
This is the output when I click on the page
有人可以帮我吗?
这是我的 Firebase
数据库结构。
这是我的 java 代码:
package com.example.atheer.booklyv1;
import android.app.ListActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class orgServices extends AppCompatActivity {
ListView ListView;
FirebaseDatabase database;
DatabaseReference ref;
ArrayList<Service> list;
ArrayAdapter<Service> adapter;
Service ser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_org_services);
ser = new Service();
ListView = (ListView) findViewById(R.id.ListView);
database = FirebaseDatabase.getInstance();
ref =database.getReference().child("client");
list = new ArrayList<>();
adapter = new ArrayAdapter<Service>(this, R.layout.service_info,R.id.serviceInfo,list);
ref.addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
for(DataSnapshot ds: dataSnapshot.getChildren())
{
if (dataSnapshot.hasChild("services")){
ser= ds.getValue(Service.class);
list.add(ser);}
}
ListView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError){
}
});
}
}
这是 ListView 的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".orgServices">
<ListView
android:id="@+id/ListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</android.support.constraint.ConstraintLayout>
这是 ListView 中每个元素的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/serviceInfo"
android:textSize="30sp"
android:text="Name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
我定制了适配器 class: 适配器 class :
package com.example.atheer.booklyv1;
import android.support.v7.app.AppCompatActivity;
public class Service extends AppCompatActivity {
private int price;
private String name;
private int totalpoint;
private int rating;
public Service(){
}
public Service (String name){
this.name=name;
}
public Service (String name, int price , int totalpoint , int rating ){
this.name=name;
this.price=price;
this.totalpoint=totalpoint;
this.rating=rating;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTotalpoint() {
return totalpoint;
}
public void setTotalpoint(int totalpoint) {
this.totalpoint = totalpoint;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
}
这些消息来自 运行 部分:
V/FA: Recording user engagement, ms: 748436
V/FA: Connecting to remote service
V/FA: Activity paused, time: 1449333
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=748436, firebase_screen_class(_sc)=Service, firebase_screen_id(_si)=-4092656992746331939}]
I/atheer.booklyv: Waiting for a blocking GC ProfileSaver
V/FA: Connection attempt already in progress
V/FA: Connection attempt already in progress
Activity resumed, time: 1449354
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=Service, firebase_previous_id(_pi)=-4092656992746331939, firebase_screen_class(_sc)=Mynavigation, firebase_screen_id(_si)=-4092656992746331940}]
I/atheer.booklyv: WaitForGcToComplete blocked ProfileSaver on ProfileSaver for 62.701ms
V/FA: Connection attempt already in progress
D/EGL_emulation: eglMakeCurrent: 0xebd05420: ver 3 0 (tinfo 0xebd033e0)
D/FA: Connected to remote service
V/FA: Processing queued up service tasks: 4
V/FA: Recording user engagement, ms: 3384
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@6a2bdcc
V/FA: Activity paused, time: 1452737
V/FA: onActivityCreated
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=3384, firebase_screen_class(_sc)=Mynavigation, firebase_screen_id(_si)=-4092656992746331940}]
V/FA: Activity resumed, time: 1452998
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=Mynavigation, firebase_previous_id(_pi)=-4092656992746331940, firebase_screen_class(_sc)=Service, firebase_screen_id(_si)=-4092656992746331938}]
D/EGL_emulation: eglMakeCurrent: 0xebd05420: ver 3 0 (tinfo 0xebd033e0)
问题出在使用 dataSnapshot
检索时。您正在做的是,如果您找到名称为 services
的 child,您将尝试从 Services.class
.[=22= 中的当前 dataSnapshot
获取数据]
您应该做的是,在您选择的 child 上设置正确的 databaseReference
。
因此,您可以在 if
语句中试试这个,而不是您用来检索的代码:
String name = dataSnapshot.child("name").getValue(String.class);
String name = dataSnapshot.child("price").getValue(Integer.class);
String name = dataSnapshot.child("rating").getValue(Integer.class);
String name = dataSnapshot.child("totalpoint").getValue(Integer.class);
如果你想在不设置不同的 getValue()
语句的情况下获取所有值,你可以使用 map
来实现。这可以帮助您同时从数据库中更新和检索值。
您可以参考以下 link 了解更多关于使用 map
从 FirebaseDatabase
检索数据的信息。
要解决这个问题,只需移动以下代码行:
adapter = new ArrayAdapter<Service>(this, R.layout.service_info,R.id.serviceInfo,list);
之前:
ListView.setAdapter(adapter);
当您设置适配器时,您的列表是空的,这就是为什么屏幕是空的。