Удаление одной строки SQlite RecyclerView onSwiped - PullRequest
0 голосов
/ 22 января 2019

Я храню текстовые элементы в адаптере RecyclerView и в поставщике контента.Список доступен из пункта меню.Элементы удаляются смахиванием.В настоящее время элементы сохраняются, но не удаляются.Я отладил, и он показывает, что «id» равен 0 (не извлекается в основной активности):

int id = (int) viewHolder.itemView.getTag();

Выбранный элемент не удаляется с экрана.Я основываю свой код на этой структуре:

https://www.javatips.net/api/ud851-Exercises-master/ud851-Exercises-student/Lesson09-ToDo-List/T09.07-Solution-SwipeToDelete/app/src/main/java/com/example/android/todolist/MainActivity.java

Я посмотрел эту ветку и связанные темы в этом посте, и мой код должен работать.Он работал раньше в другом проекте.Проблема с курсором в классе Избранное адаптер?Заранее благодарим.

Проведите, чтобы уволить для RecyclerView

А также этот поток:

Удаление строки в SQLite в Android

Методы onSwiped и Loader Cursor в основном действии:

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;
    }

RecyclerViewAdapter:

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 Ответ

0 голосов
/ 22 января 2019

Изменение

rowDeleted = db.delete (TubeLineContract.TubeLineEntry.TABLE_NAME, "id =?", новая строка [] {id});

К

rowDeleted = db.delete (TubeLineContract.TubeLineEntry.TABLE_NAME, "id =?", новая строка [] {String.valueOf (id)});

in Метод удаления ContentProvider .

...