将数据从云 Firestore 传递到 ListView

Passing data from cloud Firestore to ListView

我正在尝试从 Cloud Firestore 获取我的数据并将其传递到 ListView。目前,我的代码需要将总线名称传递给 ArrayList,然后传递给 ListView。

MainActivity.java

public class busTimetable extends AppCompatActivity {

private static final String TAG = "busTimetable";

FirebaseFirestore fStore;
private ListView lv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ongoing_bus);
    fStore = FirebaseFirestore.getInstance();

    lv = (ListView) findViewById(R.id.listView);
    lv.setEmptyView(findViewById(R.id.empty));
    //ArrayList<String> arrayList = new ArrayList<String>();
    
    foo(new Callback() {
        @Override
        public void myResponseCallback(ArrayList<String> result) {

            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
                    this,
                    android.R.layout.simple_list_item_1,
                    result);

            lv.setAdapter(arrayAdapter);
        }
    });

}

interface Callback {
    void myResponseCallback(ArrayList<String> result);//whatever your return type is: string, integer, etc.
}

public void foo(final Callback callback) {
    fStore.collection("drivers")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            String busName = document.getString("fName");
                            boolean ongoing = document.getBoolean("ongoing");
                            Log.d(TAG, "SUCCESSFULL GET USER DATA");
                            ArrayList<String> arrayList = new ArrayList<String>();

                            if (ongoing) {
                                arrayList.add(busName);
                                callback.myResponseCallback(arrayList);
                            }
                        }
                    }
                }
            });


}

}

ongoing_bus.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/no_results" />

</LinearLayout>

Firestore 数据库结构

Screenshot of my database structure

如果我没有在代码中添加 arrayList.add("busName");

我的 ListView 不会显示任何结果,但是当我添加代码时,它会显示代码的结果,但在其顶部显示文本 busName。我希望显示没有“busName”文本的公交车名称。

here is the sample of expected output

您的代码中没有任何内容表明在您的列表中添加了“busName”,位置为零。但是,如果您像下面这样重构代码,您将获得将列表添加到回调的正确方法:

public void foo(final Callback callback) {
    fStore.collection("drivers")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        ArrayList<String> arrayList = new ArrayList<>();
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            String busName = document.getString("fName");
                            boolean ongoing = document.getBoolean("ongoing");
                            Log.d(TAG, "SUCCESSFULL GET USER DATA");

                            if (ongoing) {
                                arrayList.add(busName);
                            }
                        }
                        callback.myResponseCallback(arrayList);
                    }
                }
            });

更改的内容:

  • 从循环中创建了 ArrayList。这样,您将创建一个实例,而不是在每次迭代时创建一个实例。
  • 出于完全相同的原因,将 ArrayList 添加到循环外的回调。

看看下面的代码。您的 onComplete 方法中的代码会及时运行,因此当它运行时您可以将接收到的数据添加到适配器本身,而不是数组,它会自动通知 ListView 它需要更新。


public class busTimetable extends AppCompatActivity {

    private static final String TAG = "busTimetable";

    FirebaseFirestore fStore;
    private ListView lv;
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ongoing_bus);
        fStore = FirebaseFirestore.getInstance();

        lv = (ListView) findViewById(R.id.listView);
        lv.setEmptyView(findViewById(R.id.empty));
        
        // Create an empty adapter - no items set yet
        adapter = new ArrayAdapter<String>(
                    this,
                    android.R.layout.simple_list_item_1);
        lv.setAdapter(adapter);
                    
        // call the async method - when it completes (some time in the future)
        // it will add stuff to the adapter
        fStore.collection("drivers")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        
                        ArrayList<String> arrayList = new ArrayList<String>();
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            String busName = document.getString("fName");
                            boolean ongoing = document.getBoolean("ongoing");
                            Log.d(TAG, "SUCCESSFULL GET USER DATA");
                            
                            if (ongoing) {
                                arrayList.add(busName);
                            }
                        }
                        
                        adapter.clear();
                        adapter.addAll(arrayList);
                    }
                }
            });

        // This will always print "0" - it runs before the code above
        // in the onComplete callback
        Log.d(TAG, "Adapter size = " + adapter.getCount());
    }