流式布局, 这个概念在移动端或者前端开发中很常见,特别是在多标签的展示中, 往往起到了关键的作用。公司最近要做一个标签管理,标签可删除,可添加,长按可以拖动。网上很多流式布局的列子,大部分都不能满足需求,大部分都不能拖动,有的可以拖动但是都是GridView式布局所以不能满足流式布局的基本要求,所以自己封装一个可删除,可添加,长按可以拖动流式布局。
为甚麽选择在RecyclerView基础上封装那,原因很简单:原生RecyclerView满足可拖拽,删除,添加。但是RecyclerView布局管理器满足满足不了需求,所以需要自定义:
ChipsLayoutManager spanLayoutManager = ChipsLayoutManager.newBuilder(activity)
.setOrientation(ChipsLayoutManager.HORIZONTAL)
.build();
这个ChipsLayoutManager在这里也不再多讲,详解都在github:https://github.com/BelooS/ChipsLayoutManager
适配器代码
public class TagReAdapter extends BaseRecyclerAdapter {
SwipeMenuRecyclerView recyclerView;
public TagReAdapter(Context context, List mdatas) {
super(context, mdatas);
}
@Override
public RecyclerView.ViewHolder onCreate(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.tag_item, null);
return new ViewHohler(view);
}
@Override
public void onBind(RecyclerView.ViewHolder viewHolder, int position, ShortcutNameBean bean) {
ViewHohler hohler= (ViewHohler) viewHolder;
hohler.tvName.setText(bean.getKey());
hohler.imDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
deleteClickListener.ClickListener(position,bean);
}
});
}
//拖拽的主要实现方法
public void move(int origin, int target) {
if (origin < target) {
for (int i = origin; i < target; i++) {
Collections.swap(getDatas(), i, i + 1);
}
}
if (origin > target) {
for (int i = origin; i > target; i--) {
Collections.swap(getDatas(), i, i - 1);
}
}
notifyItemMoved(origin, target);
}
class ViewHohler extends XRecyclerView.ViewHolder {
TextView tvName;
@BindView(R.id.img_del)
ImageView imDel;
@BindView(R.id.container)
RelativeLayout container;
public ViewHohler(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
tvName=itemView.findViewById(R.id.tv_tag);
}
}
public interface DeleteClickListener{
void ClickListener(int position,ShortcutNameBean bean);
}
private DeleteClickListener deleteClickListener;
public void setDeleteClickListener(DeleteClickListener deleteClickListener) {
this.deleteClickListener = deleteClickListener;
}
}
RecyclerView提供的拖拽方法
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(mBinding.recyclerView);
private ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.LEFT
| ItemTouchHelper.DOWN
| ItemTouchHelper.RIGHT
| ItemTouchHelper.UP
, ItemTouchHelper.ACTION_STATE_IDLE) {
View view;
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//获得两个Item的位置
int originPosition = viewHolder.getAdapterPosition();
int targetPistion = target.getAdapterPosition();
//交换Adapter中对应的位置
adapter.move(originPosition, targetPistion);
flag = true;
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
//长按选中动画
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(viewHolder.itemView, "scaleX", 1.0f, 1.2f);
ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(viewHolder.itemView, "scaleY", 1.0f, 1.2f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(300);
animatorSet.playTogether(objectAnimatorX, objectAnimatorY);
animatorSet.start();
view = viewHolder.itemView;
}
if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {
ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(view, "scaleX", 1.2f, 1.0f);
ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(view, "scaleY", 1.2f, 1.0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(300);
animatorSet.playTogether(objectAnimatorX, objectAnimatorY);
animatorSet.start();
adapter.notifyDataSetChanged();
}
}
};
主要实现的思路和主要代码都贴出来了,话不多说直接上图把
变化前
由于最近项目比较慢还没写Demo,后期会上传demo.