回收站视图仅在我从房间数据库中删除后重新打开活动时更新

Posted

技术标签:

【中文标题】回收站视图仅在我从房间数据库中删除后重新打开活动时更新【英文标题】:Recycler view only updates when I reopen the Activity after deleting from Room Database 【发布时间】:2020-12-22 17:20:49 【问题描述】:

我有一个带有 Recycler 视图的片段,它显示了房间数据库中的内容。在我的适配器中,我有一个 ImageButton,单击该按钮会从列表中删除该项目。我可以确认该项目已从数据库中删除,但我的列表没有预期的行为。为了更新它,我必须再次打开活动。

回收站视图

public class WishlistFragment extends Fragment 
        private static WishlistAdapter mAdapter;
        private RecyclerView mRecyclerView;
        protected static List<String> wishlist;
        private Context context;
        protected static OnRestaurantClickedListener listener;
        private FirebaseAuth mAuth;

        public static WishlistAdapter getmAdapter() 
            return mAdapter;
        

        @Override
        public void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            context = getContext();
            mAuth = FirebaseAuth.getInstance();
            wishlist = new ArrayList<>();
            mAdapter = new WishlistAdapter(context, wishlist,getActivity(),mAuth.getCurrentUser().getUid());
            LoadWishlistTask lwt=new LoadWishlistTask(getActivity(),wishlist,mAdapter,mAuth.getCurrentUser().getUid());
            lwt.execute();

        


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
            View mContentView = inflater.inflate(R.layout.restaurants_list, container, false);
            mRecyclerView = mContentView.findViewById(R.id.recycler_view);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(mContentView.getContext()));
            mRecyclerView.setAdapter(mAdapter);
            RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
            mRecyclerView.addItemDecoration(itemDecoration);

            return mContentView;
        

        @Override
        public void onResume() 
            super.onResume();
        

        @Override
        public void onAttach(Activity activity) 
            super.onAttach(activity);
            try 
                listener = (OnRestaurantClickedListener) activity;
             catch (ClassCastException e) 
                throw new ClassCastException(activity.toString() + " must implement OnRestaurantClickedClicked");
            
        

适配器

public class WishlistAdapter extends RecyclerView.Adapter<WishlistAdapter.WishlistViewHolder> 
    private Context mContext;
    private List<String> mRestaurantIds;
    private Activity act;
    private String currentUserId;

    public WishlistAdapter(Context context, List<String> ids,Activity activity,String currentUser) 
        mRestaurantIds=ids;
        mContext = context;
        act=activity;
        currentUserId=currentUser;

    

    @Override
    public WishlistViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
        // Get layout inflater from context
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        // Inflate layout
        View rView = inflater.inflate(R.layout.item_restaurant, parent, false);

        // Return a new holder instance
        return new WishlistViewHolder(rView);
    

    @Override
    public void onBindViewHolder(final WishlistViewHolder viewHolder, final int position) 
        // Get the data model based on position
        final String id = mRestaurantIds.get(position);

        getApi().getRestaurantDetails(Integer.parseInt(id), "75be9f9e2239fe637bf9cb1b46979d91")
                .enqueue(new Callback<Restaurant_>() 
                    @Override
                    public void onResponse(Call<Restaurant_> call, Response<Restaurant_> response) 
                        final TextView name=viewHolder.nameTextView;
                        name.setText(response.body().getName());
                        final TextView rating=viewHolder.ratingTextView;
                        rating.setText(response.body().getUserRating().getAggregateRating());
                        final ImageButton remove=viewHolder.removeButton;
                        remove.setOnClickListener(new View.OnClickListener() 
                            @Override
                            public void onClick(View view) 
                                Wishlist deletedRestaurant=new Wishlist(currentUserId,id);
                                RemoveWLTask rt=new RemoveWLTask(deletedRestaurant,act,WishlistFragment.wishlist);
                                rt.execute();
                            
                        );

                        viewHolder.itemView.setOnClickListener(new View.OnClickListener() 
                            @Override
                            public void onClick(View v) 
                                WishlistFragment.listener.onRestaurantClicked(id);
                            
                        );

                    

                    @Override
                    public void onFailure(Call<Restaurant_> call, Throwable t) 
                        AlertDialog.Builder builder = new AlertDialog.Builder(act);
                        builder.setMessage("Couldn´t load restaurant details");
                        AlertDialog mDialog = builder.create();
                        mDialog.show();
                    
                );

    
    @Override
    public int getItemCount() 
        return mRestaurantIds.size();
    

    private Retrofit getRetrofit() 
        return new Retrofit.Builder()
                .baseUrl("https://developers.zomato.com/api/v2.1/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    

    private ZomatoApi getApi() 
        return getRetrofit().create(ZomatoApi.class);
    


    public class WishlistViewHolder extends RecyclerView.ViewHolder 
        public TextView nameTextView;
        public TextView ratingTextView;
        public TextView distanceTextView;
        public ImageButton removeButton;

        public WishlistViewHolder(View itemView) 
            super(itemView);
            nameTextView = itemView.findViewById(R.id.restaurantName);
            ratingTextView=itemView.findViewById(R.id.restaurantRating);
            distanceTextView=itemView.findViewById(R.id.restaurantDistance);
            removeButton=itemView.findViewById(R.id.wishlistButton);


        

    


删除任务

public class RemoveWLTask extends AsyncTask<Void,Void,Void> 
    private Wishlist deletedRestaurant;
    private DB db;
    private Activity activity;
    private List<String> wishlist;

    public  RemoveWLTask (Wishlist deletedRestaurant, Activity activity,List<String> wishlist) 
        this.deletedRestaurant=deletedRestaurant;
        this.activity=activity;
        this.db= Room.databaseBuilder(activity.getApplicationContext(), DB.class, "sample-db").build();
        this.wishlist=wishlist;

    

    @Override
    protected Void doInBackground(Void... voids) 
        while (!isCancelled())
            db.daoAcess().deleteFromWishlist(deletedRestaurant);
            break;
        
        return null;
    

    @Override
    protected void onPostExecute (Void aVoid) 

        int index = wishlist.indexOf(deletedRestaurant);
        wishlist.remove(deletedRestaurant);
        WishlistFragment.getmAdapter().notifyItemRemoved(index);
        WishlistFragment.getmAdapter().notifyItemRangeChanged(index, wishlist.size());

    

【问题讨论】:

点击您的删除按钮,您会从 Room DB 中删除项目,但不会从适配器中删除项目,也不会通知数据集更改。您必须这样做,否则您的 recyclerview 将不会显示任何更新的数据,迫使您重新加载视图(从房间 db 获取所有新数据再次丢失已删除的项目) 其实问题出在论据上 【参考方案1】:

发现错误,我需要将 deletedRestaurant.getRestaurantId() 作为参数而不是 deletedRestaurant 传递

【讨论】:

以上是关于回收站视图仅在我从房间数据库中删除后重新打开活动时更新的主要内容,如果未能解决你的问题,请参考以下文章

将回收站视图数据中的 onMove() 更改更新到房间数据库

删除房间内数据库

CoreData 仅在我重新启动应用程序后更新?

从实体中删除属性后迁移 CoreData 时出错

单击 RecyclerView 后使用 Firebase 实时数据库填充详细信息活动

在不重新加载活动的情况下更新回收站视图中的内容