【问题标题】:How to make recyclerView animate when swap or change the position of each items交换或更改每个项目的位置时如何使recyclerView动画
【发布时间】:2016-10-14 04:56:40
【问题描述】:

我想在 Android 上创建带有动画的排序。

我认为最好的方法是使用RecyclerView

为了更好的用户体验,我想展示一些动画,尤其是当RecyclerView中的项目位置发生变化时

我认为有两种类型的动画要做。

1 交换项目,例如冒泡排序

2 移位项目,例如插入排序

【问题讨论】:

    标签: android android-layout animation android-recyclerview


    【解决方案1】:

    这是您想要的示例代码。

    在您的片段或活动中。

    MyAdapter adapter = new MyAdapter(getActivity(), mDataSet);
    ItemTouchHelper.Callback callback = new RecyclerItemTouchHelper(adapter);
    ItemTouchHelper helper = new ItemTouchHelper(callback);
    helper.attachToRecyclerView(mRecyclerView);
    //Here mRecyclerView is ref of your RecyclerView & mDataSet is List of your data set.
    

    然后这是您的适配器的代码。

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
        private Context mContext;
        private List<Object> mDataSet = new ArrayList<>();
        //Replace Object with your data type
    
        public MyAdapter(Context context, List<Object> dataSet) {
            mContext = context;
            mDataSet=dataSet;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_layout, parent, false);
            return new ViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Object object = mDataSet.get(position);
            //Do your Stuff
        }
    
        public void onMove(RecyclerView recyclerView, int firstPos, int secondPos) {
            /*Do your stuff what you want 
              Notify your adapter about change in positions using notifyItemMoved method
              Shift element e.g. insertion sort*/
        }
    
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            /*Do your stuff what you want
              Swap element e.g. bubbleSort*/
        }
    
        @Override
        public int getItemCount() {
            return mDataSet.size();
        }
        public static class ViewHolder extends RecyclerView.ViewHolder {
            CardView mCardView;
    
            public ViewHolder(View itemView) {
                super(itemView);
                mCardView = (CardView) itemView.findViewById(R.id.card_view);
            }
        }
    }
    

    这里是RecyclerItemTouchHelper的代码。

        public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
                private MyAdapter mAdapter;
    
                public RecyclerItemTouchHelper(SmartSocketAdapter adapter){
                    super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
                    mAdapter = adapter;
                }
    
                @Override
                public boolean onMove(final RecyclerView recyclerView,  RecyclerView.ViewHolder viewHolder,  RecyclerView.ViewHolder target) {
                    mAdapter.onMove(recyclerView,viewHolder.getAdapterPosition(), target.getAdapterPosition());
                    return true;
                }
    
                @Override
                public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                mAdapter.onSwiped(viewHolder, direction);
        }
            }
    

    通过这种方式,您将在适配器中获得两个回调,在那里您可以通知您的适配器有关更改,并且您也可以使用 notifyItemMoved 方法制作动画。

    【讨论】:

    • 很好的答案我会尝试你的答案。我会尽快通知你的:)
    • 如果对您有帮助,请将此答案标记给其他人。
    • 我会在周末尝试您的解决方案。如果它正确,那么我会将其标记为正确答案。顺便说一句,你有没有尝试在 onMove 中添加一些动画?
    • 我刚刚使用 notifyItemMoved 尝试了默认动画。
    【解决方案2】:

    其实现在很简单,也许我回答得太晚了,但是对于那些可能仍然有同样问题的人,你可以使用 ListAdapter 而不是 RecyclerView.Adapter。 它自己处理数据。您唯一需要添加到它的构造函数的是 DiffUtil.ItemCallback 实现两个函数来告诉适配器项目是否相似(以在更改位置时处理转换)。 请记住,您必须将其实现为静态变量,因为您需要将其传递给构造函数。

    public class SampleAdapter extends ListAdapter<ListItem, BaseViewHolder> {
        private static final DiffUtil.ItemCallback<ListItem> DIFF_CALLBACK =
                new DiffUtil.ItemCallback<ListItem>() {
                    @Override
                    public boolean areItemsTheSame(@NonNull ListItem oldItem,
                                                   @NonNull ListItem newItem) {
                        return oldItem.getCode().equals(newItem.getCode()); //unique
                    }
    
                    @Override
                    public boolean areContentsTheSame(@NonNull ListItem oldItem,
                                                      @NonNull ListItem newItem) {
                        return oldItem.getName().equals(newItem.getName()) &&
                                oldItem.getIconUrl().equals(newItem.getIconUrl());
                    }
                };
    
        public SampleAdapter() {
            super(DIFF_CALLBACK);
        }
    }
    

    适配器的其余部分与您的 RecyclerView.Adapter 相同。

    第一个函数判断它们是否相同。第二个函数告诉适配器是否更改了相同项目(之前和之后)的内容,以用于 UI 更新。 您可以简单地使用此代码来更新您的新列表(带有改变位置的动画)。

    adapter.submitList(...)
    

    希望它也对你有用...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多