#android #android-recyclerview #android-asynctask #adapter #android-room
#Android #android-recyclerview #android-asynctask #адаптер #android-room
Вопрос:
У меня есть этот фрагмент с представлением Recycler, в котором отображается содержимое из базы данных Room. В моем адаптере у меня есть кнопка ImageButton, которая при нажатии удаляет элемент из списка. Я могу подтвердить, что элемент удален из базы данных, но мой список не имеет ожидаемого поведения. Для того, чтобы оно было обновлено, я должен снова открыть действие.
Просмотр Recycler
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());
}
}
Комментарии:
1. Одним нажатием кнопки удаления вы удаляете элемент из базы данных Room, но не удаляете элемент из своего адаптера и не уведомляете об изменении набора данных. Вы должны это сделать, иначе в вашем recyclerview не будет отображаться никаких обновленных данных, что вынудит вас перезагрузить представление (все новые данные из базы данных room db снова отсутствуют, удаленный элемент)
2. на самом деле проблема заключалась в аргументе
Ответ №1:
Обнаружена ошибка, мне нужно передать deletedRestaurant.getRestaurantId() в качестве аргумента вместо deletedRestaurant