从共享首选项中删除项目后如何更新 Rcyclerview

How to update Rcyclerview after removing an Item from shared preferences

我在不同的活动中有一些 recyclerview,它们的所有项目都由 sharedpreferences 指定,但是从 sharedpreferences 中删除一个项目后,recyclerview 不会更新,直到我关闭 activity 并打开它我尝试了 notifyDataSetChanged () 删除项目后但似乎不起作用,代码如下:

这是我的实用程序 class,我在其中设置了共享首选项:

public class Utils {

private static final String ALL_BOOK_KEY = "all_book_key";
private static final String ALREADY_READ_BOOKS = "already_read_books";
private static final String FAVORITE_BOOKS = "favorite_books";
private static final String CURRENTLY_READING_BOOKS = "currently_reading_books";
private static final String WANT_TO_READ_BOOKS = "want_to_read_books";
private static Utils instance;
private final SharedPreferences sharedPreferences;
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>(){}.getType();


private Utils(Context context) {

    sharedPreferences = context.getSharedPreferences("alternate_db", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();

    if (null == getAllBook()){
        initData();
    }
    if (null == getAlreadyReadBooks()){
        editor.putString(ALREADY_READ_BOOKS, gson.toJson(new ArrayList<Book>()));
        editor.commit();
    }
    if (null == getWantToReadBooks()){
        editor.putString(WANT_TO_READ_BOOKS, gson.toJson(new ArrayList<Book>()));
        editor.commit();
    }
    if (null == getCurrentlyReadingBooks()){
        editor.putString(CURRENTLY_READING_BOOKS, gson.toJson(new ArrayList<Book>()));
        editor.commit();
    }
    if (null == getFavoriteBooks()){
        editor.putString(FAVORITE_BOOKS, gson.toJson(new ArrayList<Book>()));
        editor.commit();
    }

}

private void initData() {

    ArrayList<Book> books = new ArrayList<>();

    books.add(new Book(1, "1Q84", "Haruki Murakami",
            1350,"https://upload.wikimedia.org/wikipedia/pt/thumb/a/a6/1Q84.jpg/230px-1Q84.jpg",
            "A work of maddening brilliance", "The year is 1984 and the city is Tokyo. A young woman named Aomame follows a taxi driver’s enigmatic suggestion and begins to notice puzzling discrepancies in the world around her. She has entered, she realizes, a parallel existence, which she calls 1Q84 “Q is for ‘question mark.’ A world that bears a question.” Meanwhile, an aspiring writer named Tengo takes on a suspect ghostwriting project. He becomes so wrapped up with the work and its unusual author that, soon, his previously placid life begins to come unraveled. As Aomame’s and Tengo’s narratives converge over the course of this single year, we learn of the profound and tangled connections that bind them ever closer: a beautiful, dyslexic teenage girl with a unique vision; a mysterious religious cult that instigated a shoot-out with the metropolitan police; a reclusive, wealthy dowager who runs a shelter for abused women; a hideously ugly private investigator; a mild-mannered yet ruthlessly efficient bodyguard; and a peculiarly insistent television-fee collector. A love story, a mystery, a fantasy, a novel of self-discovery, a dystopia to rival George Orwell’s 1Q84 is Haruki Murakami’s most ambitious undertaking yet: an instant best seller in his native Japan, and a tremendous feat of imagination from one of our most revered contemporary writers."));

    books.add(new Book(2,  "1984", "George Orwell", 328, "https://www.jiomart.com/images/product/600x600/rvkysatqkb/1984-hindi-george-orwell-paperback-296-pages-product-images-orvkysatqkb-p590846049-0-202111091023.jpg","follows the life of Winston Smith, a low ranking member of 'the Party', who is frustrated by the omnipresent eyes of the party, and its ominous ruler Big Brother", "1984 by George Orwell – review ‘Orwell’s novella is a warning for the human race’  Conheeneyl Sun 29 May 2016 12.00 BST War is Peace. Freedom is Slavery. Ignorance is Strength.  1984 is a dystopian novella by George Orwell published in 1949, which follows the life of Winston Smith, a low ranking member of ‘the Party’, who is frustrated by the omnipresent eyes of the party, and its ominous ruler Big Brother.  ‘Big Brother’ controls every aspect of people’s lives. It has invented the language ‘Newspeak’ in an attempt to completely eliminate political rebellion; created ‘Throughtcrimes’ to stop people even thinking of things considered rebellious. The party controls what people read, speak, say and do with the threat that if they disobey, they will be sent to the dreaded Room 101 as a looming punishment.  Orwell effectively explores the themes of mass media control, government surveillance, totalitarianism and how a dictator can manipulate and control history, thoughts, and lives in such a way that no one can escape it.  1984 The protagonist, Winston Smith, begins a subtle rebellion against the party by keeping a diary of his secret thoughts, which is a deadly thoughtcrime. With his lover Julia, he begins a foreordained fight for freedom and justice, in a world where no one else appears to see, or dislike, the oppression the protagonist opposes.  Perhaps the most powerful, effective and frightening notion of 1984 is that the complete control of an entire nation under a totalitarian state is perfectly possible. If the world fell under the control of one or even multiple dictators, the future could easily become a twisted, cruel world where every movement, word and breath is scrutinised by an omnipotent, omnipresent power that no one can stop, or even oppose without the fear of death.  How do I get involved in the Guardian children\'s books site? Read more Orwell’s novella is a warning for the human race. It highlights the importance of resisting mass control and oppression."));

    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(ALL_BOOK_KEY, gson.toJson(books));
    editor.commit();
}


public static Utils getInstance(Context context) {
    if (null == instance) {
        instance = new Utils(context);
    }
    return instance;
}

public ArrayList<Book> getAllBook() {
    return gson.fromJson(sharedPreferences.getString(ALL_BOOK_KEY, null), type);
}

public ArrayList<Book> getAlreadyReadBooks() {
    return gson.fromJson(sharedPreferences.getString(ALREADY_READ_BOOKS, null),type);
}

public ArrayList<Book> getWantToReadBooks() {
    return gson.fromJson(sharedPreferences.getString(WANT_TO_READ_BOOKS, null), type);
}

public ArrayList<Book> getCurrentlyReadingBooks() {
    return gson.fromJson(sharedPreferences.getString(CURRENTLY_READING_BOOKS,null), type);
}

public ArrayList<Book> getFavoriteBooks() {
    return gson.fromJson(sharedPreferences.getString(FAVORITE_BOOKS, null), type);
}

public Book getBookById(int id) {
    ArrayList<Book> books = getAllBook();

    if(null != books){
        for (Book b : books) {
            if (b.getId() == id) {
                return b;
            }
        }
    }

    return null;
}

public boolean addToAlreadyReadBook(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getAlreadyReadBooks();
    if(null != books){
        if (books.add(book)){
            return addToSharedPreferences(books, ALREADY_READ_BOOKS);
        }
    }
    return false;
}

public boolean addToWantToReadBook(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getWantToReadBooks();
    if(null != books){
        if(books.add(book)){
            return addToSharedPreferences(books, WANT_TO_READ_BOOKS);
        }
    }
    return false;
}

public boolean addToCurrentlyReading(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getCurrentlyReadingBooks();
    if(null != books){
        if(books.add(book)){
            return addToSharedPreferences(books, CURRENTLY_READING_BOOKS);
        }
    }
    return false;
}

public boolean addToFavorite(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getFavoriteBooks();
    if(null != books){
        if(books.add(book)){
            return addToSharedPreferences(books, FAVORITE_BOOKS);
        }

    }

    return false;
}

public boolean removeFromWantToRead(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getWantToReadBooks();
    if(null != books){
        for (Book b: books){
            if(b.getId() == book.getId()){
                if (books.remove(b)){
                    return addToSharedPreferences(books, WANT_TO_READ_BOOKS);
                }
            }
        }

    }
    return false;
}

public boolean removeFromAlreadyReadBook(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getAlreadyReadBooks();
    if(null != books){
        for (Book b: books){
            if(b.getId() == book.getId()){
                if (books.remove(b)){
                    return addToSharedPreferences(books, ALREADY_READ_BOOKS);
                }
            }
        }

    }
    return false;
}

public boolean removeFromFavoriteBook(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getFavoriteBooks();
    if(null != books){
        for (Book b: books){
            if(b.getId() == book.getId()){
                if (books.remove(b)){
                    return addToSharedPreferences(books, FAVORITE_BOOKS);
                }
            }
        }

    }
    return false;
}

public boolean removeFromCurrentlyReadingBook(Book book){
    book.setExpanded(false);
    ArrayList<Book> books = getCurrentlyReadingBooks();
    if(null != books){
        for (Book b: books){
            if(b.getId() == book.getId()){
                if (books.remove(b)){
                    return addToSharedPreferences(books, CURRENTLY_READING_BOOKS);
                }
            }
        }

    }
    return false;
}

public boolean addToSharedPreferences(ArrayList<Book> books, String name){
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.remove(name);
    editor.putString(name, gson.toJson(books));
    editor.commit();
    return true;
}

}

这是我的 recyclerview 采纳者 class 我正在调用负责从实用程序 class 内的共享首选项中删除项目的方法,每当用户单击警报对话框中的是按钮时:

public class BookRecAdopter extends RecyclerView.Adapter<BookRecAdopter.ViewHolder>{

private static final String TAG = "BookRecAdopter";
private ArrayList<Book> books = new ArrayList<>();
private final Context mContext;
private final String parentActivity;

public BookRecAdopter(Context mContext, String parentActivity) {
    this.mContext = mContext;
    this.parentActivity = parentActivity;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_book, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") int position) {
    Log.d(TAG, "onBindViewHolder: Called");
    holder.txtName.setText(books.get(position).getName());
    Glide.with(mContext).asBitmap().load(books.get(position).getImageUrl()).into(holder.imgBook);

    holder.parent.setOnClickListener(view -> {
        Intent intent = new Intent(mContext, BookActivity.class);
        intent.putExtra(BOOK_ID_KEY, books.get(position).getId());
        mContext.startActivity(intent);
    });


    holder.txtAuthor.setText(books.get(position).getAuthor());
    holder.txtDescription.setText(books.get(position).getShortDesc());
    holder.bookNameFull.setText(books.get(position).getName());

    if (books.get(position).isExpanded()){
        TransitionManager.beginDelayedTransition(holder.parent);
        holder.expandedRelLayout.setVisibility(View.VISIBLE);
        holder.downArrow.setVisibility(View.GONE);
        holder.txtName.setVisibility(View.GONE);
        switch (parentActivity) {
            case "allBook":
                holder.btnDelete.setVisibility(View.GONE);
                break;
            case "wantToReadBook":
                holder.btnDelete.setVisibility(View.VISIBLE);
                holder.btnDelete.setOnClickListener(view -> {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                    builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                    builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                        if (Utils.getInstance(mContext).removeFromWantToRead(books.get(position))) {
                            Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                            notifyDataSetChanged();
                        }
                    });
                    builder.setNegativeButton("No", (dialogInterface, i) -> {

                    });
                    builder.create().show();

                });
                break;
            case "alreadyReadBook":
                holder.btnDelete.setVisibility(View.VISIBLE);
                holder.btnDelete.setOnClickListener(view -> {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                    builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                    builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                        if(Utils.getInstance(mContext).removeFromAlreadyReadBook(books.get(position))){
                            Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                            notifyDataSetChanged();

                        }
                    });
                    builder.setNegativeButton("No", (dialogInterface, i) -> {

                    });
                    builder.create().show();

                });
                break;
            case "favoriteBook":
                holder.btnDelete.setVisibility(View.VISIBLE);
                holder.btnDelete.setOnClickListener(view -> {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                    builder.setMessage("are you sure you want to delete " + books.get(position).getName() + "?");
                    builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                        if(Utils.getInstance(mContext).removeFromFavoriteBook(books.get(position))){
                            Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                            notifyDataSetChanged();

                        }
                    });
                    builder.setNegativeButton("No", (dialogInterface, i) -> {

                    });
                    builder.create().show();

                });
                break;
            case "currentlyReadBook":
                holder.btnDelete.setVisibility(View.VISIBLE);
                holder.btnDelete.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                        builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                if(Utils.getInstance(mContext).removeFromCurrentlyReadingBook(books.get(position))){
                                    Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                                    notifyDataSetChanged();

                                }
                            }
                        });
                        builder.setNegativeButton("No", (dialogInterface, i) -> {

                        });
                        builder.create().show();

                    }
                });
                break;
        }
    }
    else{
        TransitionManager.beginDelayedTransition(holder.parent);
        holder.expandedRelLayout.setVisibility(View.GONE);
        holder.downArrow.setVisibility(View.VISIBLE);
        holder.txtName.setVisibility(View.VISIBLE);
    }
    
}


@Override
public int getItemCount() {
    return books.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    private final CardView parent;
    private final ImageView imgBook;
    private final ImageView downArrow;
    private final TextView txtName, txtAuthor, txtDescription, bookNameFull, btnDelete;
    private final RelativeLayout expandedRelLayout;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        parent = itemView.findViewById(R.id.parent);
        imgBook = itemView.findViewById(R.id.imgBook);
        txtName = itemView.findViewById(R.id.txtBookName);
        downArrow = itemView.findViewById(R.id.btnDownArrow);
        ImageView upArrow = itemView.findViewById(R.id.btnUpArrow);
        expandedRelLayout = itemView.findViewById(R.id.expandedRelLayout);
        txtAuthor = itemView.findViewById(R.id.txtAuthor);
        txtDescription = itemView.findViewById(R.id.txtShortDec);
        bookNameFull = itemView.findViewById(R.id.bookNameFull);
        btnDelete = itemView.findViewById(R.id.btnDelete);

        downArrow.setOnClickListener(view -> {
            Book book = books.get(getAdapterPosition());
            book.setExpanded(!book.isExpanded());
            notifyItemChanged(getAdapterPosition());
        });

        upArrow.setOnClickListener(view -> {
            Book book = books.get(getAdapterPosition());
            book.setExpanded((!book.isExpanded()));
            notifyItemChanged(getAdapterPosition());
        });

    }
}

public void setBooks(ArrayList<Book> books) {
    this.books = books;
    notifyDataSetChanged();
}

}

这是其中一个活动,其中有一个 recyclerview,它从 sharedprefereces 中获取项目:

public class Favorite extends AppCompatActivity {
RecyclerView favoriteRec;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_favorite);

    favoriteRec = findViewById(R.id.favoriteRec);
    BookRecAdopter books = new BookRecAdopter(this, "favoriteBook");
    books.setBooks(Utils.getInstance(this).getFavoriteBooks());
    favoriteRec.setAdapter(books);
    favoriteRec.setLayoutManager(new LinearLayoutManager(this));
}

@Override
public void onBackPressed(){
    Intent intent = new Intent(this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    overridePendingTransition(R.anim.close_in, R.anim.close_out);
}

}

我想我必须重写一些回调方法以在共享首选项发生任何更改后更新 recyclerview,但我不知道是哪一个以及在哪里

感谢任何帮助。

首先,在配置您的 RecyclerView 时,在其适配器之前设置其布局管理器:

BookRecAdopter books = new BookRecAdopter(this, "favoriteBook");
favoriteRec.setLayoutManager(new LinearLayoutManager(this));
favoriteRec.setAdapter(books);

然后,鉴于您的项目结构,我认为您应该直接从 Utils class.
填充适配器的数据 尝试在适配器内部定义一个内部方法来更新图书列表 (updateBooks),并在每次删除和初始化后调用它。

public class BookRecAdopter extends RecyclerView.Adapter<BookRecAdopter.ViewHolder>{

    private static final String TAG = "BookRecAdopter";
    private ArrayList<Book> books = new ArrayList<>();
    private final Context mContext;
    private final String parentActivity;

    public BookRecAdopter(Context mContext, String parentActivity) {
        this.mContext = mContext;
        this.parentActivity = parentActivity;
        updateBooks();
    }

    private void updateBooks() {
        switch (parentActivity) {
            case "allBook":
                this.books = Utils.getInstance(mContext).getAllBooks();
                break;
            case "wantToReadBook":
                this.books = Utils.getInstance(mContext).getWantToReadBooks();
                break;
            case "alreadyReadBook":
                this.books = Utils.getInstance(mContext).getAlreadyReadBooks();
                break;
            case "favoriteBook":
                this.books = Utils.getInstance(mContext).getFavoriteBooks();
                break;
            case "currentlyReadBook":
                this.books = Utils.getInstance(mContext).getCurrentlyReadingBooks();
                break;
            default:
                break;
        }
        this.notifyDataSetChanged();
    }

    ...

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") int position) {
        ...

        if (books.get(position).isExpanded()){
            ...
            switch (parentActivity) {
                case "wantToReadBook":
                    holder.btnDelete.setVisibility(View.VISIBLE);
                    holder.btnDelete.setOnClickListener(view -> {
                        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                        builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                        builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                            if (Utils.getInstance(mContext).removeFromWantToRead(books.get(position))) {
                                Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                                updateBooks();
                            }
                        });
                        builder.setNegativeButton("No", (dialogInterface, i) -> {

                        });
                        builder.create().show();

                    });
                    break;
                case "alreadyReadBook":
                    holder.btnDelete.setVisibility(View.VISIBLE);
                    holder.btnDelete.setOnClickListener(view -> {
                        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                        builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                        builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                            if(Utils.getInstance(mContext).removeFromAlreadyReadBook(books.get(position))){
                                Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                                updateBooks();
                            }
                        });
                        builder.setNegativeButton("No", (dialogInterface, i) -> {

                        });
                        builder.create().show();

                    });
                    break;
                case "favoriteBook":
                    holder.btnDelete.setVisibility(View.VISIBLE);
                    holder.btnDelete.setOnClickListener(view -> {
                        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                        builder.setMessage("are you sure you want to delete " + books.get(position).getName() + "?");
                        builder.setPositiveButton("Yes", (dialogInterface, i) -> {
                            if(Utils.getInstance(mContext).removeFromFavoriteBook(books.get(position))){
                                Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                                updateBooks();
                            }
                        });
                        builder.setNegativeButton("No", (dialogInterface, i) -> {

                        });
                        builder.create().show();

                    });
                    break;
                case "currentlyReadBook":
                    holder.btnDelete.setVisibility(View.VISIBLE);
                    holder.btnDelete.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                            builder.setMessage("Are you sure you want to delete " + books.get(position).getName() + "?");
                            builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    if(Utils.getInstance(mContext).removeFromCurrentlyReadingBook(books.get(position))){
                                        Toast.makeText(mContext, "Book Removed", Toast.LENGTH_SHORT).show();
                                        updateBooks();
                                    }
                                }
                            });
                            builder.setNegativeButton("No", (dialogInterface, i) -> {

                            });
                            builder.create().show();

                        }
                    });
                    break;
            }
        }
        ...
    }