如何在片段内的 recylerview 列表中显示 SQLite 数据库数据?
Posted
技术标签:
【中文标题】如何在片段内的 recylerview 列表中显示 SQLite 数据库数据?【英文标题】:How to show SQLite database data in a recylerview list which is inside a fragment? 【发布时间】:2018-04-24 15:35:54 【问题描述】:我是一名业余 android 开发人员,我想从数据库中获取用户输入的项目,然后将其显示在片段中的 recyclerview 列表(不是 ListView)中。
到目前为止,我已经创建了将数据保存到其中的 SQLite 数据库,我只想知道我可以在 recyclerview 中显示所有这些信息。下面显示的 Java 代码显示了我想要制作的内容,但它位于 listview 而不是 recyclerview 中。
数据库助手
public class DatabaseHelper extends SQLiteOpenHelper
private static final String TAG = "DatabaseHelper";
public static final String DATABASE_NAME = "budget10.db";
public static final String TABLE_NAME = "expense_table";
public static final String TABLE_NAME2 = "income_table";
public static final String COL_1 = "_id";
public static final String COL_2 = "_id";
public static final String EXPENSE_AMOUNT = "EXPENSE_AMOUNT";
public static final String EXPENSE_DATE = "DATE";
public static final String EXPENSE_NOTES = "NOTES";
public static final String INCOME_AMOUNT = "INCOME_AMOUNT";
public static final String INCOME_DATE = "DATE";
public static final String INCOME_NOTES = "NOTES";
public static final String INCOME_CATEGORY = "INCOME_CATEGORY";
public static final String EXPENSE_CATEGORY = "EXPENSE_CATEGORY";
public static final String EXPENSE_ACCOUNT = "EXPENSE_ACCOUNT";
public static final String INCOME_ACCOUNT = "INCOME_ACCOUNT";
public DatabaseHelper(Context context)
super(context, DATABASE_NAME, null, 3);
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL("create table " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, EXPENSE_AMOUNT DOUBLE,DATE INTEGER,NOTES TEXT, EXPENSE_CATEGORY TEXT, EXPENSE_ACCOUNT TEXT)");
db.execSQL("create table " + TABLE_NAME2 + " (_id INTEGER PRIMARY KEY AUTOINCREMENT,INCOME_AMOUNT DOUBLE,DATE INTEGER,NOTES TEXT, INCOME_CATEGORY TEXT, INCOME_ACCOUNT TEXT)");
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME2);
onCreate(db);
public boolean insertexpenseData(Double amount_expense, String date_expense, String notes_expense, String category_expense, String expense_account)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(EXPENSE_AMOUNT, amount_expense);
contentValues.put(EXPENSE_DATE, date_expense);
contentValues.put(EXPENSE_NOTES, notes_expense);
contentValues.put(EXPENSE_CATEGORY, category_expense);
contentValues.put(EXPENSE_ACCOUNT, expense_account);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1)
return false;
else
return true;
public boolean insertincomeData(Double amount_income, String date_income, String notes_income, String category_income, String income_account)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(INCOME_AMOUNT, amount_income);
contentValues.put(INCOME_DATE, date_income);
contentValues.put(INCOME_NOTES, notes_income);
contentValues.put(INCOME_CATEGORY, category_income);
contentValues.put(INCOME_ACCOUNT, income_account);
long result = db.insert(TABLE_NAME2, null, contentValues);
if (result == -1)
return false;
else
return true;
public Cursor getexpenseData()
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
return res;
public Cursor getincomeData()
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME2, null);
return res;
public boolean updateexpenseData(String id, String amount, String date, String notes, String catagory_income)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_1, id);
contentValues.put(EXPENSE_AMOUNT, amount);
contentValues.put(EXPENSE_DATE, date);
contentValues.put(EXPENSE_NOTES, notes);
contentValues.put(EXPENSE_CATEGORY, catagory_income);
db.update(TABLE_NAME, contentValues, "_id = ?", new String[]id);
return true;
public boolean updateincomeData(String id, String amount, String date, String notes, String catagory_income)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2, id);
contentValues.put(INCOME_AMOUNT, amount);
contentValues.put(INCOME_DATE, date);
contentValues.put(INCOME_NOTES, notes);
contentValues.put(INCOME_CATEGORY, catagory_income);
db.update(TABLE_NAME2, contentValues, "_id = ?", new String[]id);
return true;
public Integer deleteexpenseData(String _id)
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, "_id = ?", new String[]_id);
public Integer deleteincomeData(String _id)
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME2, "_id = ?", new String[]_id);
public double getNetBudget()
SQLiteDatabase db = this.getWritableDatabase();
String selectQuery = "SELECT TOTAL(INCOME_AMOUNT) - (SELECT TOTAL(EXPENSE_AMOUNT) FROM expense_table) FROM income_table";
Cursor cursor = db.rawQuery(selectQuery, null);
double netBudget = 0.00; // if there is no row, this will mean 0 is returned. You could also set it to -1, or throw an Exception if no record is returned
if (cursor.moveToFirst())
netBudget = cursor.getDouble(0);
cursor.close();
return netBudget;
public double getTotalExpense()
SQLiteDatabase db = this.getWritableDatabase();
String selectQuery = "SELECT TOTAL(EXPENSE_AMOUNT) FROM expense_table";
Cursor cursor = db.rawQuery(selectQuery, null);
double netExpense = 0.00; // if there is no row, this will mean 0 is returned. You could also set it to -1, or throw an Exception if no record is returned
if (cursor.moveToFirst())
netExpense = cursor.getDouble(0);
cursor.close();
return netExpense;
public double getTotalIncome()
SQLiteDatabase db = this.getWritableDatabase();
String selectQuery = "SELECT TOTAL(INCOME_AMOUNT) FROM income_table";
Cursor cursor = db.rawQuery(selectQuery, null);
double netIncome = 0.00; // if there is no row, this will mean 0 is returned. You could also set it to -1, or throw an Exception if no record is returned
if (cursor.moveToFirst())
netIncome = cursor.getDouble(0);
cursor.close();
return netIncome;
public void deleteAllIncome()
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME2, null, null);
db.execSQL("delete from " + TABLE_NAME2);
db.close();
public void deleteAllExpense()
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, null, null);
db.execSQL("delete from " + TABLE_NAME);
db.close();
我想变成recyclerview的Fragment ListView
public class tab2income extends Fragment
private static final String TAG = "tab2income";
DatabaseHelper mDatabaseHelper;
private ListView mListView;
View rootView;
Cursor incomedata;
SimpleCursorAdapter sca;
DecimalFormat formatter = new DecimalFormat("0.00");
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.tab2income, container, false);
return rootView;
@Override
public void onActivityCreated( Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
mListView = (ListView) rootView.findViewById(R.id.listViewincome);
mListView.setEmptyView(rootView.findViewById(R.id.empty));
mDatabaseHelper = new DatabaseHelper(getActivity());
populateListView();
private void populateListView()
Log.d(TAG, "populateListView: Displaying data in the ListView.");
incomedata = mDatabaseHelper.getincomeData();
sca = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, incomedata, new String[]DatabaseHelper.INCOME_AMOUNT, new int[]android.R.id.text1, 0);
mListView.setAdapter(sca);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
int csrpos = incomedata.getPosition();
incomedata.moveToPosition(i);
displayNoteDate(
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_NOTES)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_DATE)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_CATEGORY)),
l,
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_ACCOUNT)));
incomedata.moveToPosition(csrpos);
);
@Override
public void onDestroy()
super.onDestroy();
incomedata.close();
public void displayNoteDate(String noteContent, String dateValue,String category, final long noteID,String account)
MaterialDialog.Builder builder= new MaterialDialog.Builder(getActivity())
.title("Income Information")
.content("Date: "+ dateValue+
"\nCategory: "+category+
"\nAccount: "+account+
"\nNote: "+noteContent)
.positiveText("close")
.negativeText("delete")
.onPositive(new MaterialDialog.SingleButtonCallback()
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)
)
.onNegative(new MaterialDialog.SingleButtonCallback()
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)
mDatabaseHelper.deleteincomeData(Long.toString(noteID));
incomedata = mDatabaseHelper.getincomeData();
sca.swapCursor(incomedata);
);
builder.show();
编辑
这是我到目前为止对 Saurov Bagchi 答案中的代码所做的事情,我的 xml 文件中有 recyclerview,单击项目时没有任何反应:
片段
public class tab2income extends Fragment implements ItemClickListener
private static final String TAG = "tab2income";
DatabaseHelper mDatabaseHelper;
private RecyclerView mListView;
View rootView;
Cursor incomedata;
SimpleCursorAdapter sca;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.tab2income, container, false);
return rootView;
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
mListView = rootView.findViewById(R.id.ListViewincome);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
mListView.setLayoutManager(layoutManager);
mDatabaseHelper = new DatabaseHelper(getActivity());
populateListView();
private void populateListView()
Log.d(TAG, "populateListView: Displaying data in the ListView.");
ArrayList<String> arrayList = new ArrayList<>();
MyAdapter myAdapter = new MyAdapter(arrayList);
mListView.setAdapter(myAdapter);
incomedata = mDatabaseHelper.getincomeData();
if(incomedata.moveToFirst())
do
arrayList.add(incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_AMOUNT)));
while (incomedata.moveToNext());
myAdapter.notifyDataSetChanged();
@Override
public void onDestroy()
super.onDestroy();
incomedata.close();
@Override
public void onClick(View view, int i)
int csrpos = incomedata.getPosition();
incomedata.moveToPosition(i);
displayNoteDate(
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_NOTES)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_DATE)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_CATEGORY)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_ACCOUNT)));
incomedata.moveToPosition(csrpos);
public void displayNoteDate(String noteContent, String dateValue,String category,String account)
MaterialDialog.Builder builder= new MaterialDialog.Builder(getActivity())
.title("Income Information")
.content("Date: "+ dateValue+
"\nCategory: "+category+
"\nAccount: "+account+
"\nNote: "+noteContent)
.positiveText("close")
.negativeText("delete")
.onPositive(new MaterialDialog.SingleButtonCallback()
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)
)
.onNegative(new MaterialDialog.SingleButtonCallback()
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)
);
builder.show();
适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
private final ArrayList<String> dataSet;
private ItemClickListener clickListener;
public MyAdapter(ArrayList<String> myDataset)
dataSet = myDataset;
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
//layout of the list item
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(ViewHolder holder, int position)
holder.mTextView.setText(dataSet.get(position));
@Override
public int getItemCount()
return dataSet.size();
public void setClickListener(ItemClickListener itemClickListener)
this.clickListener = itemClickListener;
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
final TextView mTextView;
ViewHolder(View v)
super(v);
//textview for showing results
mTextView = v.findViewById(android.R.id.text1);
v.setOnClickListener(this);
//for click
@Override
public void onClick(View view)
if (clickListener != null) clickListener.onClick(view, getAdapterPosition());
【问题讨论】:
我建议你使用新的 Android 架构组件。这很容易,并且需要更少的代码。 developer.android.com/topic/libraries/architecture/index.html 【参考方案1】:对于 RecyclerView,您需要创建自己的自定义适配器。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
private final ArrayList<String> dataSet;
private ItemClickListener clickListener;
public MyAdapter(ArrayList<String> myDataset)
dataSet = myDataset;
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
//layout of the list item
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(ViewHolder holder, int position)
holder.mTextView.setText(dataSet.get(position));
@Override
public int getItemCount()
return dataSet.size();
public void setClickListener(ItemClickListener itemClickListener)
this.clickListener = itemClickListener;
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
final TextView mTextView;
ViewHolder(View v)
super(v);
//textview for showing results
mTextView = v.findViewById(android.R.id.text1);
v.setOnClickListener(this);
//for click
@Override
public void onClick(View view)
if (clickListener != null) clickListener.onClick(view, getAdapterPosition());
那我只是重写populateListView()
方法
private void populateListView()
Log.d(TAG, "populateListView: Displaying data in the ListView.");
ArrayList<String> arrayList = new ArrayList<>();
MyAdapter myAdapter = new MyAdapter(arrayList);
mListView.setAdapter(myAdapter);
incomedata = mDatabaseHelper.getincomeData();
if(incomedata.moveToFirst())
do
arrayList.add(incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_AMOUNT)));
while (incomedata.moveToNext());
myAdapter.notifyDataSetChanged();
您还需要为每个项目点击创建一个界面。
public interface ItemClickListener
void onClick (View view, int position);
并在你的 Fragment 中实现这个接口。
public class tab2income extends Fragment implements ItemClickListener
//All of your codes
@Override
public void onClick (View view, int i)
int csrpos = incomedata.getPosition();
incomedata.moveToPosition(i);
displayNoteDate(
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_NOTES)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_DATE)),
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_CATEGORY)),
l,
incomedata.getString(incomedata.getColumnIndex(DatabaseHelper.INCOME_ACCOUNT)));
incomedata.moveToPosition(csrpos);
【讨论】:
我只是想问一下如何在片段中使用它? note ID 怎么样,它不起作用,并且约束布局 cardview 也会引发错误 另外,我尝试修复异常然后运行应用程序,但片段没有显示 recyclerview ViewHolder 仍然保持红色 我在打开片段时收到此错误“未附加布局管理器;跳过布局”以上是关于如何在片段内的 recylerview 列表中显示 SQLite 数据库数据?的主要内容,如果未能解决你的问题,请参考以下文章
Android:NullPointerException 无法将数据库加载到片段内的列表视图中