【发布时间】:2016-10-14 04:56:40
【问题描述】:
我想在 Android 上创建带有动画的排序。
我认为最好的方法是使用RecyclerView。
为了更好的用户体验,我想展示一些动画,尤其是当RecyclerView中的项目位置发生变化时
我认为有两种类型的动画要做。
1 交换项目,例如冒泡排序
2 移位项目,例如插入排序
【问题讨论】:
标签: android android-layout animation android-recyclerview
我想在 Android 上创建带有动画的排序。
我认为最好的方法是使用RecyclerView。
为了更好的用户体验,我想展示一些动画,尤其是当RecyclerView中的项目位置发生变化时
我认为有两种类型的动画要做。
1 交换项目,例如冒泡排序
2 移位项目,例如插入排序
【问题讨论】:
标签: android android-layout animation android-recyclerview
这是您想要的示例代码。
在您的片段或活动中。
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 方法制作动画。
【讨论】:
其实现在很简单,也许我回答得太晚了,但是对于那些可能仍然有同样问题的人,你可以使用 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(...)
希望它也对你有用...
【讨论】: