1. 程式人生 > >RecycleView瀑布流及上下滑動和左右拖拽

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);
}
    }

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


接下來,是實現上下滑動和左右拖拽

首先自定義一個類繼承實現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瀑布上下滑動左右

話不多說,先上圖:demo中使用到的圖片框架是compile 'com.github.bumptech.glide:glide:3.7.0'Activity佈局:<?xml version="1.0" encoding="utf-8"?> <Relative

RecycleView 瀑布 glide網路載入圖片

package com.example.recycleview_jinjie; //第一步 import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.s

關於RecyclerView實現瀑布上下滑動時item之間互換位置的問題

  最近專案需求,需要RecyclerView實現瀑布流。在用 StaggeredGridLayoutManager 完成瀑布流的過程中發現一個問題:它並不像pullToRefresh 那樣是穩定的list,而是item之間頻繁交換位置,有時候甚至會出現第一列和第二列完全互

OKGO RecycleView 瀑布

1.導依賴 //OKGO implementation 'com.lzy.net:okgo:3.0.4' //RecycleView implementation 'com.android.support:design:28.0.0' 2.佈局 <android.supp

RecycleView瀑布沒有數據

wid eight message nag tla sorted orien ext int package com.jiuxi.marriage.module.goods.manager; import android.content.Context; import

用jQuery實現瀑布滾動懶載入(相容IE8)

上篇 js原生瀑布流並實現滾動懶載入(相容IE8) 講解了瀑布流的原理及滾動懶載入的原理,並用原生js實現了效果,那麼原生js必定有些繁瑣和麻煩,這一篇我們就換成jQuery,程式碼會簡潔很多,思路和原理我就不贅述了,如果想看的話,移步 js原生瀑布流並實

RecyclerView 實現瀑布點選事件,含點選回撥的介面

RecyclerView 實現瀑布流及點選事件 public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> { private List

Android高仿秒拍熱榜的卡片滑動左右飛出效果--SwipeCardsView

來由 之所以做這個效果是因為專案中有這個效果需要實現。 一開始我有在github上找到不少類似的庫,但是發現放在專案中會發現要麼有鋸齒,要麼就是卡頓,總之就是效果不好,其實絕大多數的庫都和Swip

Python3 檔案讀寫OS函式

讀和寫檔案open() 將會返回一個 file 物件,基本語法格式如下: open(filename, mode)filename:包含了你要訪問的檔名稱的字串值。mode:決定了開啟檔案的模式:只讀,寫入,追加等。所有可取值見如下的完全列表。這個引數是非強制的,預設檔案訪問

Android RecycleView瀑布點選吐絲、長按刪除,很炫酷的一個列表展示

RecycleView是5.0之後推出的一個新控制元件,所以使用就要先匯入一個依賴包:        compile 'com.android.support:recyclerview-v7:22.2.1'2.實現的效果挺好看的,需要的趕緊來試一下,真的感覺跟瀑布一樣,雖然錯

原生JS實現瀑布載入效果

           瀑布流是目前一種比較流行的頁面佈局和載入效果。百度,花瓣等一些好的網站都廣泛用了這樣一種效果,適用於單頁面展示對內容的頁面。這幾天就跟著一些資料學習了一下瀑布流效果的製作。其原理是利用js動態的改

JS實現動態瀑布放大切換圖片效果(js案例)

整理了一下當時學js寫的一些案例,再次體驗了一把用原生JS實現動態瀑布流效果的樂趣,現在把它整理出來,需要的小夥伴可以參考一下。 該案例主要是用HTML+CSS控制樣式,通過JS實現全域性瀑布流以及點選圖片放大、上下切換效果。HTML佈局寫的很簡單,圖片載入主要是在JS中通過訪問自定義的JSON字串來實現。

文字左右無縫滾動效果--支援左右

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>文字左右無縫滾動

左右條改變大小

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <titl

百度地圖 點選標註後的經緯度

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html&

快速實現RecycleView的網格瀑布佈局新增頭部(尾部原理一樣,故略之)

RecycleView高度的解耦,非常靈活,通過佈局管理器LayoutManager控制其顯示的佈局;通過ItemDecoration控制Item間的間隔;通過ItemAnimator控制Item增刪的動畫;不過需要自己寫介面實現點選、長按事件。它只管回收與複用

原來操控介面可以這麼簡單----安卓上下滑動縮放頂部圖片,左右滑動結束當前Activity,View柔和回彈效果

先上效果圖: 上傳圖片不能超過2M,費了好大勁。每一張gif動的有點快,將就看。 首先說原理: 為activity的xml檔案根佈局新增setOnTouchListener。上下滑動和左右滑動的所有操作都是在OnTouchListener的onTouch方法中實現的,通過

Recycleview實現複雜頁面 三種以上佈局 瀑布 多佈局 scrollview巢狀recyclerView 顯示不全 滑動衝突 之進階終極篇 (轉載)

=============================================================================================== 相信很多安卓開發的朋友,尤其是剛從事安卓開發的朋友, 當產品經理遞過來一張複雜頁面的

Android之RecycleView使用(瀑布管理器線性管理器)

public class RecyclerActivity extends Activity { @Bind(R.id.rv) RecyclerView rv; private List<Map> list; @Override protected voi

ViewPage左右滑動PullToRefreshListView上下滑動事件衝突

這裡,相當於是PullToRefreshView嵌套了ViewPager,那麼每次優先接收到Touch事件的必然是PullToRefreshView。這樣就清楚了,看程式碼: 在PullToRefre