我正在将文本项目存储在 RecyclerView 适配器和内容提供程序中。该列表可从菜单选项访问。通过轻扫删除项目。目前,正在保存这些项目,但未将其删除。我已经调试过了,它显示“id”是0(在主活动中没有被检索):
int id = (int) viewHolder.itemView.getTag();
所选项目未从屏幕上滑出。我的代码基于以下结构:
https://www . Java tips . net/API/ud 851-Exercises-master/ud 851-Exercises-student/lesson 09-ToDo-List/t 09.07-Solution-SwipeToDelete/app/src/main/Java/com/example/Android/todolist/main activity . Java
我已经看过这个线程和那篇文章中的链接线程,我的代码应该可以工作。它之前在另一个项目中工作过。“收藏夹适配器”类中的游标是否存在问题?提前感谢您。
滑动以解雇回收人员视图
以及此线程:
在 Android 的 SQLite 中刪除行
主活动中的onSwiped和Loader游标方法:
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT| ItemTouchHelper.RIGHT)
{
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
{
return false;
}
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof LinesAdapter.LinesAdapterViewHolder) return 0;
return super.getSwipeDirs(recyclerView, viewHolder);
}
// Called when a user swipes left or right on a ViewHolder
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
// Here is where you'll implement swipe to delete
//Construct the URI for the item to delete
//[Hint] Use getTag (from the adapter code) to get the id of the swiped item
// Retrieve the id of the task to delete
int id = (int) viewHolder.itemView.getTag();
// Build appropriate uri with String row id appended
String stringId = Integer.toString(id);
Uri uri = TubeLineContract.TubeLineEntry.CONTENT_URI;
uri = uri.buildUpon().appendPath(stringId).build();
int rowsDeleted = getContentResolver().delete(uri,null, null);
Log.v("CatalogActivity", rowsDeleted + " rows deleted from the line database");
getSupportLoaderManager().restartLoader(FAVORITES_LOADER_ID, null, MainActivity.this);
}
}).attachToRecyclerView(mLineRecyclerView);
/*
* Starting the asyncTask so that lines load upon launching the app.
*/
if (savedInstanceState == null)
{
if (isNetworkStatusAvailable(this))
{
TubeLineAsyncTask myLineTask = new TubeLineAsyncTask(this);
myLineTask.execute(NetworkUtils.buildLineUrl());
} else
{
Snackbar
.make(mCoordinatorLayout, "Please check your internet connection", Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", new MyClickListener())
.show();
}
} else {
linesArrayList = savedInstanceState.getParcelableArrayList(KEY_LINES_LIST);
linesAdapter.setLinesList(linesArrayList);
}
getSupportLoaderManager().initLoader(FAVORITES_LOADER_ID, null, MainActivity.this);
favoritesAdapter = new FavoritesAdapter(this, MainActivity.this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, final Bundle loaderArgs)
{
return new AsyncTaskLoader<Cursor>(this)
{
// Initialize a Cursor, this will hold all the task data
Cursor mFavoritesData = null;
// onStartLoading() is called when a loader first starts loading data
@Override
protected void onStartLoading()
{
if (mFavoritesData != null)
{
// Delivers any previously loaded data immediately
deliverResult(mFavoritesData);
}
else
{
// Force a new load
forceLoad();
}
}
// loadInBackground() performs asynchronous loading of data
@Override
public Cursor loadInBackground()
{
// Will implement to load data
// Query and load all task data in the background; sort by priority
// [Hint] use a try/catch block to catch any errors in loading data
try
{
return getContentResolver().query(TubeLineContract.TubeLineEntry.CONTENT_URI,
null,
null,
null,
TubeLineContract.TubeLineEntry.COLUMN_LINES_ID);
}
catch (Exception e)
{
Log.e(LOG_TAG, "Failed to asynchronously load data.");
e.printStackTrace();
return null;
}
}
// deliverResult sends the result of the load, a Cursor, to the registered listener
public void deliverResult(Cursor data)
{
mFavoritesData = data;
super.deliverResult(data);
}
};
}
/**
* Called when a previously created loader has finished its load.
*
* @param loader The Loader that has finished.
* @param data The data generated by the Loader.
*/
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
favoritesAdapter.swapCursor(data);
if (mPosition == RecyclerView.NO_POSITION) mPosition = 0;
mLineRecyclerView.smoothScrollToPosition(mPosition);
}
/**
* Called when a previously created loader is being reset, and thus
* making its data unavailable.
* onLoaderReset removes any references this activity had to the loader's data.
*
* @param loader The Loader that is being reset.
*/
@Override
public void onLoaderReset(Loader<Cursor> loader)
{
favoritesAdapter.swapCursor(null);
}
ContentProvider删除方法:
// Implement delete to delete a single row of data
@Override
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs)
{
// Get access to the database and write URI matching code to recognize a single item
final SQLiteDatabase db = mTubeLineDbHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
// Keep track of the number of deleted rows
int rowsDeleted; // starts as 0
//if (null == selection) selection = "1";
// Write the code to delete a single row of data
// [Hint] Use selections to delete an item by its row ID
switch (match)
{
// Handle the single item case, recognized by the ID included in the URI path
case LINE_WITH_ID:
// Get the line ID from the URI path
String id = uri.getPathSegments().get(1);
// Use selections/selectionArgs to filter for this ID
rowsDeleted = db.delete(TubeLineContract.TubeLineEntry.TABLE_NAME, "id=?", new String[]{id});
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
// Notify the resolver of a change and return the number of items deleted
if (rowsDeleted != 0)
{
// A line was deleted, set notification
getContext().getContentResolver().notifyChange(uri, null);
}
// Return the number of rows deleted
return rowsDeleted;
}
回收器视图适配器:
public class FavoritesAdapter extends RecyclerView.Adapter<FavoritesAdapter.FavoritesAdapterViewHolder>
{
private static final String TAG = FavoritesAdapter.class.getSimpleName();
private Context context;
private Cursor cursor;
private LinesAdapter.LinesAdapterOnClickHandler mClickHandler;
public FavoritesAdapter(LinesAdapter.LinesAdapterOnClickHandler clickHandler, Context context)
{
mClickHandler = clickHandler;
this.context = context;
}
public class FavoritesAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
@BindView(R.id.line_name)
TextView lineName;
public FavoritesAdapterViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
cursor.moveToPosition(getAdapterPosition());
String lineName = cursor.getString(cursor.getColumnIndexOrThrow(TubeLineContract.TubeLineEntry.COLUMN_LINES_NAME));
String lineId = cursor.getString(cursor.getColumnIndexOrThrow(TubeLineContract.TubeLineEntry.COLUMN_LINES_ID));
Lines lines = new Lines(lineName, lineId);
mClickHandler.onClick(lines);
}
}
@Override
public void onBindViewHolder(FavoritesAdapter.FavoritesAdapterViewHolder holder, int position)
{
// get to the right location in the cursor
cursor.moveToPosition(position);
// Determine the values of the wanted data
int lineIdIndex = cursor.getColumnIndexOrThrow(TubeLineContract.TubeLineEntry.COLUMN_LINES_ID);
int lineNameColumnIndex = cursor.getColumnIndexOrThrow(TubeLineContract.TubeLineEntry.COLUMN_LINES_NAME);
final int id = cursor.getInt(lineIdIndex);
String stationName = cursor.getString(lineNameColumnIndex);
holder.itemView.setTag(id);
holder.lineName.setText(stationName);
Log.e(TAG, "Failed to load line text.");
}
@Override
public FavoritesAdapter.FavoritesAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.line_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new FavoritesAdapter.FavoritesAdapterViewHolder(view);
}
public Cursor swapCursor(Cursor c)
{
// check if this cursor is the same as the previous cursor (mCursor)
if (cursor == c)
{
return null; // bc nothing has changed
}
Cursor temp = cursor;
this.cursor = c; // new cursor value assigned
//check if this is a valid cursor, then update the cursor
if (c != null)
{
this.notifyDataSetChanged();
}
return temp;
}
@Override
public int getItemCount()
{
if (null == cursor)
return 0;
return cursor.getCount();
}
}
变化
rowsDeleted = db.delete(TubeLineContract.TubeLineEntry.TABLE_NAME, “id=?”, new String[]{id});
到
db.delete(TubeLineContract.TubeLineEntry.TABLE_NAME,"id=?", new String[]{String.valueOf(id)});
在 ContentProvider delete method 中。
如果用户点击一个,我希望它做一些事情,也为两个和三个。我如何实现这一点?
有什么想法如何将其转化为单点击解决方案吗?建议,甚至是一个单独的评论,都会帮我很大的忙。
我使用此解决方案来过滤我的。使用该解决方案,我能够在键入时获得结果。但是当我清除搜索小部件时,我没有得到完整的列表,而是得到了空的。 这就是我的结果。https://imgur.com/nwyetEd 这是我的 这是我的 这是我使用过滤器的< code >活动 有人能帮助我吗?
我有一个滑动删除,它绘制了一个背景(很像收件箱应用程序),由ItemTouchHelper实现,方法是覆盖onChilDraw方法并在提供的画布上绘制一个矩形: 上面调用的删除方法位于适配器中: 背景画得很好,但是当调用notefyItemRemved时(根据调试器先生的说法),RecyclerView首先删除我漂亮的绿色背景,然后将两个相邻的项目推到一起。 我希望它在这样做的时候保持背景(就像收
我添加了一个自定义的< code > ItemTouchHelper。我的< code > recycle view 的SimpleCallback类,以添加“滑动时消除”功能,用户可以向左滑动项目,项目将从列表中删除。 我将视图可以“滑动”到左侧的量限制为视图长度的 10%,方法是将 dX(来自 onChildDraw())除以 10。但是,用户必须滑动的长度量是屏幕的 100%,以便项目被滑动
问题内容: 嗨,我正在尝试通过下面的查询删除表中的所有行 我正在表中删除n行。但是表中仍然存在行。我的删除通话有什么问题吗? 问题答案: 您需要先调用以将对数据库所做的所有更改提交给数据库,然后再调用: 来源(Android开发人员参考): 如果任何事务未标记为干净而结束(通过调用setTransactionSuccessful),则更改将回滚。否则,他们将被提交。