在RecyclerView上删除项目时没有animation
我第一次使用RecyclerView
。 一切都工作正常,除了没有项目删除animation,即使在项目添加animation工作得很好。
我没有设置任何自定义项目animation师,但根据文档 :
RecyclerView
默认启用添加和删除项目的animation。
所以去除animation应该工作。
我想有删除的默认animation,但不能得到这个工作。
这是我如何设置RecyclerView:
private void setupRecyclerView() { mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); View emptyView = mRootView.findViewById(R.id.empty_view); mAdapter = new RoutineAdapter(getActivity(), mRoutineItems, emptyView); mRecyclerView.setAdapter(mAdapter); }
这是我的适配器:
private class RoutineAdapter extends RecyclerView.Adapter<RoutineAdapter.ViewHolder> { private final Context mContext; private List<RoutineItem> mData; private View mEmptyView; public RoutineAdapter(Context context, List<RoutineItem> data, View emptyView) { mContext = context; mData = data; mEmptyView = emptyView; setEmptyViewVisibility(); } public void add(RoutineItem routineItem, int position) { mData.add(position, routineItem); setEmptyViewVisibility(); notifyItemInserted(position); } public void remove(int position){ mData.remove(position); setEmptyViewVisibility(); notifyItemRemoved(position); } public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final View view = LayoutInflater.from(mContext).inflate( R.layout.fragment_routines_list_item, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, final int position) { final RoutineItem routineItem = getItem(position); holder.circle.setBackgroundResource( colorNumberToDrawableResource(routineItem.colorNumber)); holder.initial.setText(routineItem.routineName.substring(0, 1)); holder.routineName.setText(routineItem.routineName); holder.lastTimeDone.setText(routineItem.lastTimeDoneText); if (routineItem.isSelected) { holder.itemView.setBackgroundColor( getResources().getColor(R.color.background_item_selected)); } else { holder.itemView.setBackgroundResource( R.drawable.darker_background_on_pressed); } holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPresenter.onRoutineClicked(routineItem.routineName); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mPresenter.onRoutineLongClicked(routineItem.routineName); return true; } }); } @Override public int getItemCount() { return mData.size(); } public RoutineItem getItem(int position) { return mData.get(position); } private void setEmptyViewVisibility() { if (getItemCount() == 0) { mEmptyView.setVisibility(View.VISIBLE); } else { mEmptyView.setVisibility(View.GONE); } } class ViewHolder extends RecyclerView.ViewHolder { public final View circle; public final TextView initial; public final TextView routineName; public final TextView lastTimeDone; public ViewHolder(View view) { super(view); circle = view.findViewById(R.id.circle); initial = (TextView) view.findViewById(R.id.initial); routineName = (TextView) view.findViewById(R.id.routine_name); lastTimeDone = (TextView) view.findViewById(R.id.last_time_done); } } }
Fragment_routines_list_item.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:minHeight="@dimen/standard_list_item_height" android:paddingBottom="8dp" android:background="@drawable/darker_background_on_pressed" android:clickable="true"> ...... </RelativeLayout>
我在做什么错误,导致默认删除animation无法正常工作?
从回收站视图中删除项目的正确方法是从数据集中删除项目,然后告诉适配器该项目被删除
myDataset.remove(position); // myDataset is List<MyObject> mAdapter.notifyItemRemoved(position);
解决了它。
问题是,在调用mAdapter.remove(position)
,我的代码的另一部分是调用mAdapter.notifyDataSetChanged()
,我假设停止删除animation。
总而言之,如果在正在进行animation的过程中调用mAdapter.notifyDataSetChanged
,则animation将停止。
使用notifyItemRemoved(position)
而不是notifyDataSetChanged()
如下所示
myDataset.remove(position); notifyItemRemoved(position);
因为notifyDataSetChanged()
只是在没有任何animation的情况下通知更新的数据。
另一个不正确的删除animation的原因可能是RecyclerViews
高度。 validation高度是match_parent
而不是wrap_content
!
我能够通过animation和更新的索引删除视图,如下所示:
在适配器内,
public boolean removeItem(int position) { if (data.size() >= position + 1) { data.remove(position); return true; } return false; }
在删除视图时,请致电
if (adapter.removeItem(position)) { adapter.notifyItemRemoved(position); adapter.notifyItemRangeChanged(position, adapter.getItemCount()); }
我已经使用了布尔方法来确保双击等等。 不要导致崩溃。
经过长时间的debugging,我意识到我必须将setHasStableIds(true)
添加到我的适配器并实现
@Override public long getItemId(int position) { return position; }
之后,删除animation开始工作
我遇到了同样的问题,我通过实施我自己的RecyclerView来解决这个问题,在我的回收查看中,我这样做了:
public class MyRecyclerView extends RecyclerView { private View mEmptyView; private AdapterDataObserver mDataObserver = new AdapterDataObserver() { public void onChanged() { super.onChanged(); updateEmptyView(); } public void onItemRangeRemoved(int positionStart, int itemCount) { super.onItemRangeRemoved(positionStart, itemCount); updateEmptyView(); } public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); updateEmptyView(); } }; // private void setAdapter() {} private void updateEmptyView() { // update empty view's visibility } }
基本上,当你向/从recyclerview中添加/删除项目时,可以调用notifyItemInserted()/ notifyItemRemoved()和notifyItemRangeChanged(),这些方法将调用onItemRangeRemoved()
/ onItemRangeInserted()
。 所以在这些方法中,你可以更新空视图的可见性,并且不会破坏animation。
- 如何在Android中获取/设置媒体音量(不是铃声音量)?
- android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码14):无法打开数据库
- 如何在Android Studio中打开现有的Eclipse项目?
- 为Android应用程序设置ActionBarSherlock主题
- 我在哪里可以find在线的Android源代码?
- 我怎样才能安装apk到多个连接的设备?
- 如果在WebView中按下返回按钮,如何返回上一页?
- Android Studio 0.4复制在APK META-INF / LICENSE.txt中复制的文件
- TabLayout选项卡select