我目前正在Android Studio中开发移动应用。我在Firebase Firestore中有一个名为Leagues的收藏。当我从导航抽屉中打开一个片段时,recyclerview是空的。我在布局的顶部有两个按钮,两个按钮都打开一个警报对话框。当我单击两个按钮中的任何一个并单击框以开始输入文本时,联赛就会神奇地出现在recyclerview中!理想情况下,我希望它们在首次打开片段时出现。为了提供更多的上下文信息,我有一个方法可以从Firebase中的集合中获取联赛,但是在对其进行调试之后,我发现它最初会返回一个空列表。仅当按下警报对话框中的edittext框时,列表才会填充。谁能想到为什么会这样?
预先感谢
编辑:
public class LeaguesFragment extends Fragment {
Button buttonCreateLeague;
Button buttonJoinLeague;
View view;
FirebaseFirestore firestore;
private String leagueID;
private String userID;
private String leagueName;
private String username;
TextView textViewMyLeagues;
RecyclerView recyclerView;
private List<Leagues> leaguesList;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_leagues, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.leaguesList);
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(getContext(), leaguesList);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(recyclerViewAdapter);
buttonCreateLeague = (Button) view.findViewById(R.id.buttonCreateLeague);
buttonJoinLeague = (Button) view.findViewById(R.id.buttonJoinLeague);
textViewMyLeagues = (TextView) view.findViewById(R.id.textViewMyLeagues);
firestore = FirebaseFirestore.getInstance();
userID = FirebaseAuth.getInstance().getUid();
firestore.collection("users").document(userID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
username = documentSnapshot.getString("name");
}
}
});
buttonCreateLeague.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
leagueID = CreateLeagueID.randomString(6);
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("Enter league name");
final EditText input = new EditText(getContext());
alert.setView(input);
alert.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
leagueName = input.getText().toString().trim();
createLeague(leagueID, leagueName);
addUserToLeague(leagueID, username);
addLeagueToUser(leagueID, userID, leagueName);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled.
}
});
alert.show();
}
});
buttonJoinLeague.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("Enter league code");
final EditText input = new EditText(getContext());
alert.setView(input);
alert.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
leagueID = input.getText().toString().trim();
firestore.collection("leagues").document(leagueID).collection("members").document(username).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if(documentSnapshot.exists()) {
Toast.makeText(getActivity(), "Already part of this league", Toast.LENGTH_SHORT).show();
}
else {
firestore.collection("leagues").document(leagueID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if (documentSnapshot.exists()) {
leagueName = documentSnapshot.getString("leagueName");
addUserToLeague(leagueID, username);
addLeagueToUser(leagueID, userID, leagueName);
}
else {
Toast.makeText(getActivity(), "That league does not exist", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
}
});
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled.
}
});
alert.show();
}
});
return view;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
leaguesList = new ArrayList<>();
firestore = FirebaseFirestore.getInstance();
userID = FirebaseAuth.getInstance().getUid();
firestore.collection("users").document(userID).collection("leagues").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
if(e != null) {
Log.d(TAG, "Error : " + e.getMessage());
}
for(DocumentChange doc: queryDocumentSnapshots.getDocumentChanges()) {
if(doc.getType() == DocumentChange.Type.ADDED) {
//leagueID = doc.getDocument().getString("leagueID");
//leagueName = doc.getDocument().getString("leagueName");
Leagues leagues = doc.getDocument().toObject(Leagues.class);
leaguesList.add(leagues);
}
}
}
});
}
答案 0 :(得分:0)
已调试它,我发现它最初会返回一个空列表。
是的,这是正常行为。您现在不能使用尚未加载的内容。换句话说,您不能简单地将leaguesList
变量创建为全局变量,并在onEvent()
方法之外使用它,因为由于该方法的异步行为,它将始终为空。这意味着,当您尝试在该方法之外使用该列表时,数据尚未完成从数据库的加载,因此无法访问。快速解决此问题的方法是仅在leaguesList
方法内使用onEvent()
列表,否则我建议您从此 post 在其中,我解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。
答案 1 :(得分:0)
也许问题是当触发onCreateView时,您的LeaguesList仍然为空。而且,当来自Firestore的onEvent触发时,您不会通知数据集更改适配器。