当前位置: 首页 > 知识库问答 >
问题:

删除单个 SQlite 行回收器查看已擦拭

林蕴藉
2023-03-14

我正在将文本项目存储在 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();

        }
    }

共有1个答案

法和安
2023-03-14

变化

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 >活动 有人能帮助我吗?

  • 我添加了一个自定义的< code > ItemTouchHelper。我的< code > recycle view 的SimpleCallback类,以添加“滑动时消除”功能,用户可以向左滑动项目,项目将从列表中删除。 我将视图可以“滑动”到左侧的量限制为视图长度的 10%,方法是将 dX(来自 onChildDraw())除以 10。但是,用户必须滑动的长度量是屏幕的 100%,以便项目被滑动

  • 我有一个滑动删除,它绘制了一个背景(很像收件箱应用程序),由ItemTouchHelper实现,方法是覆盖onChilDraw方法并在提供的画布上绘制一个矩形: 上面调用的删除方法位于适配器中: 背景画得很好,但是当调用notefyItemRemved时(根据调试器先生的说法),RecyclerView首先删除我漂亮的绿色背景,然后将两个相邻的项目推到一起。 我希望它在这样做的时候保持背景(就像收

  • 问题内容: 嗨,我正在尝试通过下面的查询删除表中的所有行 我正在表中删除n行。但是表中仍然存在行。我的删除通话有什么问题吗? 问题答案: 您需要先调用以将对数据库所做的所有更改提交给数据库,然后再调用: 来源(Android开发人员参考): 如果任何事务未标记为干净而结束(通过调用setTransactionSuccessful),则更改将回滚。否则,他们将被提交。