如何使用适配器在Android ListView中显示Firestore集合 [英] How to show a firestore Collection in an Android ListView using an Adapter
问题描述
我正在开发一个简单的应用程序,需要在我的应用程序中查看特定FirebaseFirestore
集合中的每个文档.
I am working on a simple app where I need to see every document in a specific FirebaseFirestore
collection in my app.
为使此工作有效,我认为最好的解决方案是将ListView
与自定义ArrayAdapter
结合使用.并将Firestore文档强制转换为我创建的自定义Java类.
To make this work, I thought the best solution would be to use a ListView
with a custom ArrayAdapter
. And have the Firestore document be cast to a custom java class I made.
我的文档设置为:
(字符串)标题:
(日期)到期日期:
(Number)exp:
(Number) exp :
(字符串)说明:
但是,按照我的逻辑,某些事情似乎不起作用.下面是我用于此过程的代码:
However, something in my logic seems to not work. Below is my code for this process:
Missions.java:
public class Missions {
private String title;
private Number exp;
private String date;
private String description;
public Missions() {}
public Missions(String title, Number exp, String date, String description) {
this.title = title;
this.exp = exp;
this.date = date;
this.description = description;
}
public String getTitle(){
return title;
}
public Number getExp(){
return exp;
}
public String getDate(){
return date;
}
public String getDescription(){
return description;
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final String COLLECTION_KEY = "missions";
//Views
private TextView mHeaderView;
private ListView mMissionListView;
//Firebase
private FirebaseFirestore db;
//Adapter
private MissionsAdapter mMissionAdapter;
private ArrayList<Missions> mMissionsList;
@Override
protected void onCreate(Bundle savedInstanceState){
/*
* My code here deals with authentication
*
*/
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHeaderView = (TextView) findViewById(R.id.missionHeader);
mMissionsListView = (ListView) findViewById(R.id.missionList);
mHeaderView.setText("Available Missions"));
//get Database
db = FirebaseFirestore.getInstance();
//Set up the ArrayList
mMissionsList = new ArrayList<Missions>();
//set the Adapter
mMissionAdapter = new MissionsAdapter(this, mMissionsList);
mMissionListView.setAdapter(mMissionAdapter);
db.collection(COLLECTION_KEY).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot document : task.getResult()){
Log.d("MissionActivity", document.getId() + " => " + document.getData());
Missions miss = document.toObject(Missions.class);
mMissionsList.add(miss);
}
}
else {
Log.d("MissionActivity", "Error getting documents: ", task.getException());
}
}
});
//add the whole Arraylist of MIssions to the adapter
mMissionAdapter.addAll(mMissionsList);
}
}
MissionsAdapter.java
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class MissionsAdapter extends ArrayAdapter<Missions> {
public MissionsAdapter(Context context, List<Missions> object){
super(context,0, object);
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = ((Activity)getContext()).getLayoutInflater().inflate(R.layout.item_mission,parent,false);
}
TextView titleTextView = (TextView) convertView.findViewById(R.id.mission_title);
TextView expTextView = (TextView) convertView.findViewById(R.id.mission_exp);
TextView dateTextView = (TextView) convertView.findViewById(R.id.mission_date);
TextView descriptionTextView = (TextView) convertView.findViewById(R.id.mission_description);
Missions mission = getItem(position);
titleTextView.setText(mission.getTitle());
expTextView.setText(mission.getExp().toString());
dateTextView.setText(mission.getDate());
descriptionTextView.setText(mission.getDescription());
return convertView;
}
}
item_missions.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/mission_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="@color/input_login"
android:hint="There will be a title"/>
<TextView
android:id="@+id/mission_exp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textAppearance="?android:textAppearance"
android:textColor="@color/input_login"
android:hint="There will be exp"/>
<TextView
android:id="@+id/mission_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textAppearance="?android:textAppearance"
android:textColor="@color/input_login"
android:hint="There will be a date"/>
<TextView
android:id="@+id/mission_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textAppearance="?android:textAppearance"
android:textColor="@color/input_login"
android:hint="There will be a description"/>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/missionHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Edit/Create mission"
android:gravity="center"
android:textStyle="bold"
android:textColor="@android:color/black"
android:textAllCaps="true"
android:textSize="30dp"
android:paddingTop="20dp"
/>
<ListView
android:id="@+id/missionList"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
任何评论都会有所帮助.
Any comment would be helpful.
推荐答案
您快到了.代码中的问题是,您试图用一个空列表填充适配器,这是因为到执行此操作时,您还没有完成从数据库中获取数据的过程.请注意,onComplete()
方法具有异步行为.要解决此问题,请使用以下代码:
You're almost there. The problem in your code is that you are trying to populate the adapter with a list that is empty and this is because by the time you are doing this, you haven't finished getting the data from the database. Note that the onComplete()
method has an asynchronous behaviour. To solve this, please use the following code:
db.collection(COLLECTION_KEY).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
List<Missions> mMissionsList = new ArrayList<>();
if(task.isSuccessful()){
for(QueryDocumentSnapshot document : task.getResult()) {
Missions miss = document.toObject(Missions.class);
mMissionsList.add(miss);
}
ListView mMissionsListView = (ListView) findViewById(R.id.missionList);
MissionsAdapter mMissionAdapter = new MissionsAdapter(this, mMissionsList);
mMissionsListView.setAdapter(mMissionAdapter);
} else {
Log.d("MissionActivity", "Error getting documents: ", task.getException());
}
}
});
如您所见,我已经在此方法中声明并使用了适配器.
As you can see, I have declared and used the adapter inside this method.
这篇关于如何使用适配器在Android ListView中显示Firestore集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!