[英]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.