Recyclerview не обновляется при удалении элементов - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть корзина, в которую я добавляю продукты, но у меня проблема с этим. Когда я нажимаю sh кнопку, чтобы удалить элемент, представление переработчика не обновляется после вызова также notifydatachanged (). Когда я снова перехожу к своей корзине покупок, товара там нет, потому что он удален. Но я не хочу видеть отчаяние, когда я занимаюсь покупками. Вот мой адаптер:

holder.removeProduct.setOnClickListener(v -> {
            SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
            SharedPreferences.Editor mEditor = preferences.edit();
            Gson gson = new Gson();
            String json = preferences.getString("artikujtShporta", "");
            ArrayList<Artikujt> artikullObject = gson
                    .fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());

            if (artikullObject != null) {
                int indexToRemove;
                for(int i = 0 ; i < artikullObject.size(); i++){
                    if(artikullObject.get(i).getId().equals(artikulli.getId())) {
                        indexToRemove = i;
                        artikullObject.remove(indexToRemove);
                        notifyItemRemoved(indexToRemove);
                        String jsonString = gson.toJson(artikullObject);
                        mEditor.putString("artikujtShporta", jsonString);
                        mEditor.apply();
                    }
                }
            }
        });

и мой фрагмент:

SharedPreferences preferences = Objects.requireNonNull(getContext())
                .getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
        Gson gson = new Gson();
        String json = preferences.getString("artikujtShporta", "");
        cartItems = gson.fromJson(json,  new TypeToken<ArrayList<Artikujt>>(){}.getType());

        basketAdapter = new BasketAdapter(cartItems, getContext());
        mRecyclerView = mView.findViewById(R.id.basket_recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
        mRecyclerView.setAdapter(basketAdapter);
        //basketAdapter.clear();
        //basketAdapter.addAll(cartItems);
        basketAdapter.notifyDataSetChanged();

Ответы [ 3 ]

0 голосов
/ 23 апреля 2020

Создайте интерфейс IShoppingCart, который будет реализован вашим Fragment. Мы хотим сохранить логику c в Fragment. (Лично я переместил бы эту логику c в ViewModel, но это будет касаться.)

IShoppingCart

interface IShoppingCart {
    fun addItemToCart(item: CartItem): Boolean
    fun removeItemToCart(itemId: String): Boolean

    /**
    * Feel free to add more functionality
    */
}

Теперь пройдем ваш фрагмент через композицию для вашего RecyclerViewAdapter.

RecyclerViewAdapter

ShoppingCartAdapter(val contract: IShoppingCart) : RecyclerView.Adapter<ViewHolder>() {
    .
    .
    .
}

Теперь вы можете использовать эту ссылку в своем классе ViewHolder, поскольку они, вероятно, определены как Inner Classes.

ViewHolder

holder.removeProduct.setOnClickListener(v -> {
  // This will kick in the code that lies in the Fragment
  contract.removeItemToCart(viewHolder.itemView.id)
});

Теперь в вашем Fragment, внутри removeItemToCart(val itemId), просто удалите item с заданным itemId и вызовом notifyDataSetChanged().

Фрагмент

fun DeleteItemToCart(itemId: String) {
    dataset.removeItemWithItemId(itemId)
    notifyDataSetChanged()
}

Следуя этому подходу, вам не нужно уведомлять адаптер, что весь набор данных изменился, как это не было. Вы можете просто сказать адаптеру, что изменилось только положение одного элемента (как оно было удалено), используя notifyItemRemoved(position: Int).

0 голосов
/ 23 апреля 2020

Вы можете удалить элемент в адаптере в представлении ViewHolder onClick() прослушиватель определенной строки в RecyclerView, используя getAdapterPosition(), который возвращает позицию строки, по которой щелкнули; поэтому вы добавили бы:

artikullObject.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());

Итак, изменения в вашем коде:

holder.removeProduct.setOnClickListener(v -> {
        SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
        SharedPreferences.Editor mEditor = preferences.edit();
        Gson gson = new Gson();
        String json = preferences.getString("artikujtShporta", "");
        ArrayList<Artikujt> artikullObject = gson
                .fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());

        // remove current row of the clicked item
        artikullObject.remove(getAdapterPosition());
        notifyItemRemoved(getAdapterPosition());
    });

Обновление: getAdapterPosition () не найден как метод

getAdapterPosition() - это метод ViewHolder, к которому нельзя получить доступ из класса адаптера, поэтому вы можете просто передать View.OnLongClickListener в пользовательский ViewHolder вместо пользовательского RecyclerView.Adapter адаптер.

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {

    View removeProduct;

    MyViewHolder(@NonNull View listItem) {
        super(listItem);
        // caching views
        removeProduct = listItem.findViewById(...);

        // Listen to removing a product 
        removeProduct.setOnClickListener(v -> {
            SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
            SharedPreferences.Editor mEditor = preferences.edit();
            Gson gson = new Gson();
            String json = preferences.getString("artikujtShporta", "");
            ArrayList<Artikujt> artikullObject = gson
                    .fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());

            // remove current row of the clicked item
            artikullObject.remove(getAdapterPosition());
            notifyItemRemoved(getAdapterPosition());

        });

    }

}

Примечание. Ваш подход к удалению одного элемента с помощью итерации всего списка элементов не так уж хорош с точки зрения производительности, поэтому вам просто нужно выбрать определенный индекс для удаления.

0 голосов
/ 22 апреля 2020

notifyDataSetChanged здесь для l oop:

for(int i = 0 ; i < artikullObject.size(); i++){
if(artikullObject.get(i).getId().equals(artikulli.getId())) {
indexToRemove = i;
artikullObject.remove(indexToRemove);

//here
notifyDataSetChanged();
String jsonString = gson.toJson(artikullObject);
mEditor.putString("artikujtShporta", jsonString);
mEditor.apply();
}
}

ОБНОВЛЕНИЕ

сохраните то, что я вам сказал, и убедитесь, что list то, что вы вызываете для метода .remove(indexToRemove), представляет собой фактический список, который вы передали адаптеру для заполнения данных, то есть список, который вы использовали в getItemCount()

другими словами:

I Я не уверен, если artikullObject - это список, из которого вы должны удалить объект, вы должны использовать основной список, который вы использовали для заполнения адаптера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...