我在fragment
上有两个按钮,一个按钮用于使用SQLite
显示listview
,另一个按钮使用Firebase
显示listview
。listview
和SQLite
工作,但是,尽管逻辑相同,listview
和Firebase
不工作。我可以成功地从firebase
中检索数据(我使用Toast
进行了测试,它运行得很好(,但不知何故,我无法在listview
中显示检索到的数据。
以下是片段的全部代码,包括SQLite
的listview
和Firebase
:
package com.example.dailybible3;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
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 FragmentNotes extends Fragment {
private static final String TAG = "";
private View view;
private Button btn_all_notes, btn_my_notes;
DatabaseHelper mDatabaseHelper;
private ListView mListView;
ListAdapter adapter;
ArrayList<String> listData, listData2;
public static FragmentNotes newInstance() {
FragmentNotes fragmentNotes = new FragmentNotes();
return fragmentNotes;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_notes, container, false);
//SQL
mListView = (ListView) view.findViewById(R.id.list_view);
mDatabaseHelper = new DatabaseHelper(getActivity());
populatePrivateListView();
//all note button
btn_all_notes = (Button) view.findViewById(R.id.btn_all_notes);
btn_all_notes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
populatePublicListView();
}
});
//my note button
btn_my_notes = (Button) view.findViewById(R.id.btn_my_notes);
btn_my_notes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
populatePrivateListView();
}
});
//floating button
FloatingActionButton fab = view.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), MyNotes.class));
}
});
return view;
}
private void populatePrivateListView() {
Log.d(TAG, "populatePrivateListView: Displaying PRIVATE data in the ListView.");
//get the data and append to a list
Cursor cursor = mDatabaseHelper.getData();
listData = new ArrayList<>();
while(cursor.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
listData.add(cursor.getString(1));
}
//create the list adapter and set the adapter
//customize the listview with "list_view_item"
adapter = new ArrayAdapter<String>(getContext(),R.layout.list_view_items, listData);
mListView.setAdapter(adapter);
//set an onItemClickListener to the ListView
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String name = adapterView.getItemAtPosition(i).toString();
Log.d(TAG, "onItemClick: You Clicked on " + name);
Cursor data = mDatabaseHelper.getItemID(name); //get the id associated with that name
int itemID = -1;
while(data.moveToNext()){
itemID = data.getInt(0);
}
if(itemID > -1){
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editPrivateData = new Intent(getActivity(), FragmentNotesEditPrivateData.class);
editPrivateData.putExtra("id", itemID);
editPrivateData.putExtra("name", name);
startActivity(editPrivateData);
}
else{
toastMessage("No ID associated with that name");
}
}
});
}
private void populatePublicListView() {
DatabaseReference firebase;
firebase = FirebaseDatabase.getInstance().getReference().child("Note");
//set the listview
listData2 = new ArrayList<>();
firebase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
String note = snapshot.getValue().toString();
listData2.add(note);
toastMessage(note);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
//set the listview
adapter = new ArrayAdapter<String>(getContext(),R.layout.list_view_items, listData2);
mListView.setAdapter(adapter);
}
/**
* customizable toast
* @param message
*/
private void toastMessage(String message){
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
}
这不起作用,因为您的"适配器";在某些情况下可能为null或未定义,这可能就是您的情况。要解决这个问题,您需要记住侦听器的工作就是侦听您的代码。所以,你的
String note = snapshot.getValue().toString();
listData2.add(note);
toastMessage(note);
仅当侦听器检测到快照中的更改时才实现。我还没有亲自实现或测试过你的代码,所以不能透露更多的漏洞。但我能立即想到的一个解决方案是这样的(不完全是这样(。不过,您可能需要四处玩耍,将listData2设置为静态,或者将适配器放在侦听器之外,以避免内存泄漏。试着让我知道它是否有效。
firebase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
String note = snapshot.getValue().toString();
listData2.add(note);
toastMessage(note);
adapter = new ArrayAdapter<String>(getContext(),R.layout.list_view_items, listData2);
mListView.setAdapter(adapter);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
//set the listview