话不多说,先上图:

RecycleView瀑布流及上下滑动和左右拖拽

demo中使用到的图片框架是

compile 'com.github.bumptech.glide:glide:3.7.0'

Activity布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    tools:context="com.rxd.test.Activity.RecyclerViewActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:background="@color/colorPrimaryDark"
        android:id="@+id/linearLayout">


        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textSize="18sp"
            android:text="RecycleView" />
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/linearLayout"
        android:padding="5dp"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
Item布局中使用到了cardView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#00000000">

    <android.support.v7.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="5dp"
        app:cardElevation="0px"
        android:clickable="true"
        android:foreground="?android:attr/selectableItemBackground"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="fitXY"
                />
            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:textSize="12sp"
                android:padding="8dp"
                android:background="#FFFFFF"
                />

        </LinearLayout>
    </android.support.v7.widget.CardView>

</LinearLayout>

布局就这些,接下来是代码:

主界面Activity:

public class RecyclerViewActivity extends AppCompatActivity  {


    @BindView(R.id.recycle)
    RecyclerView recycle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);
        ButterKnife.bind(this);

        final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//防止滑动时跳动
        layoutManager.invalidateSpanAssignments();
        recycle.setLayoutManager(layoutManager);
        recycle.setHasFixedSize(true);
        recycle.setNestedScrollingEnabled(false);
        recycle.addOnScrollListener(new RecyclerView.OnScrollListener() {
                                        @Override
                                        public void
                                        onScrollStateChanged(RecyclerView recyclerView,
                                                             int newState) {
                                            super.onScrollStateChanged(recyclerView,
                                                    newState);
                                            //防止第一行到顶部有空白区域
                                            layoutManager.invalidateSpanAssignments();
                                        }
                                    }
        );
        SpacesItemDecoration decoration = new SpacesItemDecoration(16);
        recycle.addItemDecoration(decoration);
        String[] url = {"https://ww1.sinaimg.cn/bmiddle/75d91745gy1fqsizpz0drj21kw2t5x6p.jpg",
                "https://ww2.sinaimg.cn/bmiddle/75d91745gy1fqsiy9ic3yj20u01hc44a.jpg",
                "https://ww3.sinaimg.cn/bmiddle/75d91745gy1fqsizlsmy5j21kw2t4e81.jpg",
                "https://ww4.sinaimg.cn/bmiddle/75d91745gy1fqsizh8b1ij21kw2t4x31.jpg",
                "https://ww3.sinaimg.cn/bmiddle/75d91745gy1fqsiylokp4j21kw2t4dqg.jpg",
                "https://ww3.sinaimg.cn/bmiddle/75d91745gy1fqsiz5p789j20u01hctpv.jpg",
                "https://ww1.sinaimg.cn/bmiddle/75d91745gy1fqsiyf51qdj20u01hc7cl.jpg",
                "https://ww3.sinaimg.cn/bmiddle/75d91745gy1fqsiyq0grij20u01hcgvc.jpg",
                "https://ww4.sinaimg.cn/bmiddle/75d91745gy1fqsiziu2z9j21kw2t57wh.jpg",
                "https://ww1.sinaimg.cn/bmiddle/0070Uq5Kly1fre1pucf2pj30j60y4tbv.jpg",
                "https://wx2.sinaimg.cn/bmiddle/0070Uq5Kly1fr8cr8dutaj30j60y2jxe.jpg",
                "https://wx2.sinaimg.cn/bmiddle/953b752bly1fr7xerd8iij20u00u0wit.jpg",
                "https://wx2.sinaimg.cn/bmiddle/62c2f0a5gy1fr62yjo8vbj215o1jktdd.jpg",
                "https://wx4.sinaimg.cn/bmiddle/beb1a021gy1fqc1528c9oj20ku0kuthc.jpg",
                "https://ww1.sinaimg.cn/bmiddle/005QiGQWgy1frb36tf9oaj31221vo44h.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005QiGQWgy1frb36u9ys9j31221vowj9.jpg",
                "https://ww3.sinaimg.cn/bmiddle/005QiGQWgy1frb36vc7isj31221vogpz.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005QiGQWgy1frb36wxzg1j31221voaeh.jpg",
                "https://ww3.sinaimg.cn/bmiddle/005QiGQWgy1frb36y10kmj31221vo7aj.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005QiGQWgy1frb36sjuevj31221vowin.jpg",
                "https://ww3.sinaimg.cn/bmiddle/005QiGQWgy1frb36zb07wj31221vo461.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005QiGQWgy1frb370inxjj31221vowkl.jpg",
                "https://ww1.sinaimg.cn/bmiddle/005QiGQWgy1fr7lkvxcboj31221vowix.jpg",
                "https://ww3.sinaimg.cn/bmiddle/005Hfi3egy1fr41wul1rij30fm0rswh4.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005Hfi3egy1fr41wvmpa2j30f00qoqpj.jpg",
                "https://ww1.sinaimg.cn/bmiddle/005Hfi3egy1fr41wvzpuaj30fm0rsjtl.jpg",
                "https://ww2.sinaimg.cn/bmiddle/005QiGQWgy1fr7lkvj38xj31221votcn.jpg",
                "https://ww1.sinaimg.cn/bmiddle/005QiGQWgy1fr916i2zs3j31jk111npd.jpg"};
        String[] desc = {"遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~", "遇见夏天~",
                "#成就更好的自己##每天心情语录##每日心情记录##情话##每天心情语录# ",
                "接受突如其来的失去,珍惜不期而遇的惊喜。", "忧心狮子座\n" +
                "趁阳光正好,\n" +
                "趁微风不噪\n" +
                "趁繁花还未开至荼蘼~\n" +
                "\n" +
                "世界太吵,\n" +
                "只需听自己的心跳,\n" +
                "一切从简,\n" +
                "做自己想做的事~",
                "当一个人心情愉快时,他便显得善良。", "心情不好吃糖就好啦~",
                "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "插画", "林允儿~~"};
      List<Itembean>  data_list = new ArrayList<>();
        for (int i = 0; i < url.length; i++) {
            //记录每张图片的高度
            int hgight = (int) (200 + Math.random() * 400);
            Itembean item = new Itembean(desc[i], url[i], hgight);
            data_list.add(item);

        }
       MyRecycleAdapter  adapter = new MyRecycleAdapter(this);
        recycle.setAdapter(adapter);
        adapter.setDataList(data_list);

        RecycleTouchHelperCallback callback = new RecycleTouchHelperCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(recycle);

    }


    public class SpacesItemDecoration extends RecyclerView.ItemDecoration {

        private int space;

        public SpacesItemDecoration(int space) {
            this.space = space;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.top = space;
            outRect.bottom = space;
            outRect.left = space;
            outRect.right = space;
        }
    }


}

ItemBean中就一个图片的url和一个name描述和一个记录图片高度的int值,代码就不贴了,为了实现瀑布流的效果,图片初始高度是随机的,记录下来是为了固定图片高度。

adapter代码:

public class MyRecycleAdapter extends RecyclerView.Adapter<MyRecycleAdapter.ViewHolder>implements ItemTouchHelperInterface {
    private List<Itembean> data_list;
    private Context context;

    public MyRecycleAdapter(Context context) {
        this.context = context;
    }

    public void setDataList(List<Itembean> data_list) {
        this.data_list = data_list;
        notifyDataSetChanged();

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false);


        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.txt.setText(data_list.get(position).getName());
        int width = ((Activity) holder.image.getContext()).getWindowManager().getDefaultDisplay().getWidth();
        Glide.with(context)
                .load(data_list.get(position).getUrl())
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .error(R.mipmap.demo)
                .crossFade()
                .centerCrop()
                .override(width / 2,data_list.get(position).getHegiht() )
                .into(holder.image);

    }

    @Override
    public int getItemCount() {
        return data_list.size();
    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        Collections.swap(data_list, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
    }

    @Override
    public void onItemDismiss(int position) {
        data_list.remove(position);
        notifyItemRemoved(position);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView image;
        private TextView txt;
        private CardView cardView;

        public ViewHolder(View itemView) {
            super(itemView);
            image = itemView.findViewById(R.id.imageView);
            txt = itemView.findViewById(R.id.textView);
            cardView = itemView.findViewById(R.id.cardView);
        }
    }


以上,瀑布流效果已经有了:

RecycleView瀑布流及上下滑动和左右拖拽

接下来,是实现上下滑动和左右拖拽

首先自定义一个类继承实现ItemTouchHelper.Callback接口

public class RecycleTouchHelperCallback extends ItemTouchHelper.Callback {
    private final  MyRecycleAdapter mAdapter;
    public RecycleTouchHelperCallback(MyRecycleAdapter adapter) {
        this.mAdapter = adapter;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int swipeFlags = 0;
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN|  ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        return  makeMovementFlags(dragFlags,swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        mAdapter.onItemMove(viewHolder.getAdapterPosition(),
                target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }
}

getMovementFlags用于设置是否处理拖拽事件和滑动事件,以及拖拽和滑动操作的方向,比如如果是列表类型的RecyclerView,拖拽只有UP、DOWN两个方向,而如果是网格类型的则有UP、DOWN、LEFT、RIGHT四个方向.

然后新建一个接口用于更新数据:

public interface ItemTouchHelperInterface {
    //用于通知底层数据的更新
    void onItemMove(int fromPosition, int toPosition);
    void onItemDismiss(int position);
}

在adapter里实现这个接口来更新数据(代码片段,上面adapter里面已经写了):

@Override
public void onItemMove(int fromPosition, int toPosition) {
    Collections.swap(data_list, fromPosition, toPosition);
    notifyItemMoved(fromPosition, toPosition);
}

@Override
public void onItemDismiss(int position) {
    data_list.remove(position);
    notifyItemRemoved(position);
}

最后 们只需要实例化一个ItemTouchHelper,然后关联到RecyclerView就OK了(代码片段,上面activity里面已经写了):

RecycleTouchHelperCallback callback = new RecycleTouchHelperCallback(adapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recycle);

拖拽过程截图如下:

RecycleView瀑布流及上下滑动和左右拖拽


第一次正经写博文,就凑合看看吧。。。

分类:

技术点:

相关文章: