Android ListView 未填充
Android ListView does not populate
我在 fragment
上有两个按钮,一个按钮使用 SQLite
显示 listview
,另一个按钮使用 Firebase
显示 listview
. listview
与 SQLite
有效,但是,尽管逻辑相同,但 listview
与 Firebase
无效。我可以从 firebase
中成功检索数据(我使用 Toast
对其进行了测试,它工作得很好),但是不知何故,我无法在 listview
.[=27= 中显示检索到的数据]
这里是片段的全部代码,包括 listview
for SQLite
和 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 静态化或将适配器放在 Listener 之外以避免内存泄漏。试试看是否有效。
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
我在 fragment
上有两个按钮,一个按钮使用 SQLite
显示 listview
,另一个按钮使用 Firebase
显示 listview
. listview
与 SQLite
有效,但是,尽管逻辑相同,但 listview
与 Firebase
无效。我可以从 firebase
中成功检索数据(我使用 Toast
对其进行了测试,它工作得很好),但是不知何故,我无法在 listview
.[=27= 中显示检索到的数据]
这里是片段的全部代码,包括 listview
for SQLite
和 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 静态化或将适配器放在 Listener 之外以避免内存泄漏。试试看是否有效。
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