[英]Update ListView in Fragment when SQLite database is updated in another Fragment
我有兩個片段
AddActivityFragment
- 這個 Fragment 負責將數據添加到我的 SQLite 數據庫中。
和
ActivityListFragment
- 這個 Fragment 負責在ListView
中顯示數據
問題在於,每當向 SQLite 表添加數據時,該表在應用程序重新啟動之前不會更新。 因此,如果我嘗試將一些數據添加到表中,則在重新啟動應用程序之前,它不會在ListView
中更新。
我在多個線程上遇到過關於類似問題的adapter.notifyDataSetChanged()
,但我一生都無法弄清楚我應該如何將其實現到我自己的代碼中。
AddActivityFragment.java
:
public class AddActivityFragment extends Fragment implements View.OnClickListener {
private static final String TAG = "AddActivityFragment";
private TextInputLayout activityNameTextField, activityDateTextField;
private TextInputEditText activityNameInput, activityDateInput;
public DatabaseHelper mDatabaseHelper;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationProviderClient;
private Location mLastLocation;
private ActivityListFragment mActivityListFragment;
private DatePicker mDatePicker;
Context mContext;
private double activityLocationLat;
private double activityLocationLong;
public AddActivityFragment() {
// Required empty public constructor
}
@Override
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View activityViewFragment = inflater.inflate(R.layout.fragment_add_activity, container, false);
// Get context from fragment.
this.mContext = activityViewFragment.getContext();
mDatabaseHelper = new DatabaseHelper(mContext);
// Find the layout components.
activityNameTextField = activityViewFragment.findViewById(R.id.activityNameTextField);
activityNameInput = activityViewFragment.findViewById(R.id.activityNameInput);
mDatePicker = activityViewFragment.findViewById(R.id.datePicker);
Button addActivityButton = activityViewFragment.findViewById(R.id.addActivityButton);
// Set listener to addActivityButton in this view.
addActivityButton.setOnClickListener(this);
// Set hints for text fields.
activityNameTextField.setHint("Activity Name");
return activityViewFragment;
}
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.addActivityButton:
StringBuilder sb = new StringBuilder();
int day = mDatePicker.getDayOfMonth();
int month = mDatePicker.getMonth() + 1;
int year = mDatePicker.getYear();
sb.append(day);
sb.append("-");
sb.append(month);
sb.append("-");
sb.append(year);
String activityName = activityNameInput.getText().toString();
String activityDate = sb.toString();
activityNameInput.setText("");
//Add the activity data to the SQL database
mDatabaseHelper.addData(activityName,activityDate,activityLocationLat,activityLocationLong);
break;
default:
break;
}
@Override
public void onResume(){
super.onResume();
Log.d(TAG,"Log when activity is swiped to.");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "List paused.");
}
}
ActivityListFragment.java
:
public class ActivityListFragment extends Fragment {
//Class tag
private static final String TAG = "ActivityListFragment";
private static final String ACTIVITY_LIST_FRAGMENT_TAG = "ACTIVITY_LIST_FRAGMENT";
DatabaseHelper mDatabaseHelper;
Context mContext;
private ListView mListView;
public ArrayAdapter adapter;
private ArrayList<ArrayList> listData;
public ActivityListFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View listViewFragment = inflater.inflate(R.layout.fragment_activity_list, container, false);
this.mContext = listViewFragment.getContext();
mListView = listViewFragment.findViewById(R.id.activity_list_view);
mDatabaseHelper = new DatabaseHelper(mContext);
listData = new ArrayList<>();
for(int i = 0; i < mDatabaseHelper.getRowCount(); i++) {
listData.add(mDatabaseHelper.getDataFromIndex(i));
}
adapter = new ArrayAdapter<>(mContext, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
handleOnItemClick();
return listViewFragment;
}
@Override
public void onResume(){
super.onResume();
Log.d(TAG,"Log when activity is swiped to.");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "List paused.");
}
ViewPagerAdapter.java
:
public class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new MapViewFragment();
case 1:
return new AddActivityFragment();
case 2:
return new ActivityListFragment();
}
return null;
}
@Override
public int getItemCount() {
return 3;
}
}
DataBaseHelper.java
:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
//Table name, column names.
private static final String TABLE_NAME = "activity_table";
private static final String COL_ID = "ID";
private static final String COL_NAME = "name";
private static final String COL_DATE = "date";
private static final String COL_LOCATION_LAT = "location_lat";
private static final String COL_LOCATION = "location_long";
private Cursor mCursor;
ArrayList latLongList;
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
/**
* Method: onCreate
* @param db - The database that we are creating the table in.
*/
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_ACTIVITES_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ COL_ID + " INTEGER PRIMARY KEY," + COL_NAME + " VARCHAR,"
+ COL_DATE + " VARCHAR," + COL_LOCATION_LAT + " DOUBLE," + COL_LOCATION + " DOUBLE" + ");";
db.execSQL(CREATE_ACTIVITES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
/**
* Method: addData
* @param name - The "name"-value which is added to the table column COL_NAME.
* @param date - The "date"-value which is added to the table column COL_DATE.
* @param locationLat - The "locationLat"-value which is added to the table column COL_LOCATION_LAT.
* @param locationLong - The "locationLong"-value which is added to the table column COL_LOCATION_LONG.
* @return true or false, depending if the addition to the table was successful or not.
*/
public boolean addData(String name, String date, Double locationLat, Double locationLong) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_NAME, name);
contentValues.put(COL_DATE, date);
contentValues.put(COL_LOCATION_LAT, locationLat);
contentValues.put(COL_LOCATION, locationLong);
Log.d(TAG, "addData: Adding " + name + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + date + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + locationLat + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + locationLong + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
if(result == -1) {
Log.d(TAG, "Something went wrong when adding data to database.");
return false;
} else {
Log.d(TAG, "Data correctly added to database");
return true;
}
}
/**
* Method: getData
* @return mCursor - Returns entire table from database.
*/
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
mCursor = db.rawQuery(query, null);
return mCursor;
}
/**
* Method: getDataFromIndex
* @param index - Row index in activity_table table.
* @return list - ArrayList of data at row index.
*/
public ArrayList getDataFromIndex (int index) {
ArrayList list = new ArrayList();
if(mCursor == null) {
getData();
}
mCursor.moveToPosition(index);
list.add(mCursor.getString(1));
list.add(mCursor.getString(2));
list.add(mCursor.getDouble(3));
list.add(mCursor.getDouble(4));
return list;
}
/**
* Method: getRowCount
* @return mCursor.getCount - Total amount of rows in table.
*/
public int getRowCount() {
if(mCursor == null) {
getData();
}
return mCursor.getCount();
}
/** TODO: This might be useless as we will need to fetch the names associated to the activity anyway, to be decided.
* Method: latLongArrayListFromIndex
* @param index - Row index in activity_table table.
* @return latLongList - ArrayList of data at row index.
*/
public ArrayList latLongArrayListFromIndex(int index) {
latLongList = new ArrayList();
if(mCursor == null) {
getData();
}
mCursor.moveToPosition(index);
latLongList.add(mCursor.getDouble(mCursor.getColumnIndex("location_lat")));
latLongList.add(mCursor.getDouble(mCursor.getColumnIndex("location_long")));
return latLongList;
}
/**
* Method getItemId
*/
public Cursor getItemId(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL_ID + " FROM " + TABLE_NAME + " WHERE " + COL_NAME + " = '" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Method: updateName
* @param newName
* @param id
* @param oldName
*/
public void updateName(String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL_NAME + " = '" + newName + "' WHERE " + COL_ID + " = '" + id + "'" + " AND " + COL_NAME + " = '" + oldName + "'";
Log.d(TAG, "updateName: query: " + query);
Log.d(TAG, "updateName: Setting new name of activity to: " + newName);
db.execSQL(query);
}
public void deleteActivity(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE " + COL_ID + " = '" + id + "'" + " AND " + COL_NAME + " = '" + name + "'";
Log.d(TAG, "deleteActivity: query: " + query);
Log.d(TAG, "deleteActivity: Deleting " + name + " from table");
db.execSQL(query);
}
}
您只需使用內容觀察器觀察 SQLite 數據即可實現所需的行為。 我在這里有一個 Github 項目,它可能會幫助您了解它是如何工作的。
第一步是定義一個唯一的內容 URI。 URI 可能如下所示。
public static final Uri DB_TABLE_USER_URI = Uri
.parse("sqlite://" + com.package.your.app + "/" + "user_table");
然后使用ActivityListFragment
中的LoaderManager.LoaderCallbacks<Cursor>
使用CursorLoader
回調函數(即onCreateLoader
、 onLoadFinished
等)加載該片段中的用戶。 還要在您的onCreateLoader
中注冊內容觀察者。
this.registerContentObserver(cursor, DBConstants.DB_TABLE_USER_URI);
在DataBaseHelper
class 中添加/更新用戶后,您可能還想通知觀察者數據庫中的數據已更改,以便它在RecyclerView
中自動刷新數據。
context.getContentResolver().notifyChange(DBConstants.DB_TABLE_USER_URI, null);
我建議分叉 Github 項目並運行代碼以查看它是如何工作的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.