Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android---UI---RecyclerView實現瀑布流

android---UI---RecyclerView實現瀑布流

編輯:關於Android編程

一.包引入

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
    //包引入
    compile 'com.android.support:recyclerview-v7:+'
}

二.布局文件

主界面引入RecyclerView:




    

RecyclerView的item布局文件:




    
    

這裡添加一個ImageView和TextView

適配器類MasonryAdapter:

繼承RecyclerView.Adapter,並重寫裡面的方法:

private List products;


    public MasonryAdapter(List list) {
        products = list;
    }

    @Override
    public MasonryView onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.masonry_item, viewGroup, false);
        return new MasonryView(view);
    }

    @Override
    public void onBindViewHolder(MasonryView masonryView, int position) {
        masonryView.imageView.setImageResource(products.get(position).getImg());
        masonryView.textView.setText(products.get(position).getTitle());

    }

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

    public static class MasonryView extends RecyclerView.ViewHolder {

        ImageView imageView;
        TextView textView;

        public MasonryView(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView.findViewById(R.id.masonry_item_img);
            textView = (TextView) itemView.findViewById(R.id.masonry_item_title);
        }

    }

三個方法:
1. onCreateViewHolder()` 方法用於找到子item的布局文件,並返回視圖。

2. onBindViewHolder()用於數據綁定,從列表裡面獲取數據,注意其中一個參數MasonryView masonryView是需要自定義的。
繼承RecyclerView.ViewHolder` 用於找到item裡面的布局控件。

public static class MasonryView extends RecyclerView.ViewHolder {

        ImageView imageView;
        TextView textView;

        public MasonryView(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView.findViewById(R.id.masonry_item_img);
            textView = (TextView) itemView.findViewById(R.id.masonry_item_title);
        }

    }

3.getItemCount返回條目總數。

自定義類Product:

這個不解釋,就是一個類,包括了所需的變量。

public class Product {
    private int img;
    private String title;

    public Product(int img, String title) {
        this.img = img;
        this.title = title;
    }

    public int getImg() {
        return img;
    }

    public void setImg(int img) {
        this.img = img;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

使用RecyclerView:

在主Activity裡面使用RecyclerView:
1.定義Product List 並做數據初始化,添加數據。
2.找到RecyclerView控件
3.設置LayoutManager,設置布局為 流式布局StaggeredGridLayoutManager,寬度為2.
4.綁定數據Adaper。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recycler);
        //設置layoutManager
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //設置adapter
        initData();
        Log.d("xxxx", productList.toString());
        MasonryAdapter adapter = new MasonryAdapter(productList);
        recyclerView.setAdapter(adapter);
        }
        public void initData() {
        productList = new ArrayList();
        productList.add(new Product(R.drawable.ic_1, "美女1"));
        productList.add(new Product(R.drawable.ic_2, "美女1"));
        productList.add(new Product(R.drawable.ic_3, "美女1"));
        productList.add(new Product(R.drawable.ic_1, "美女1"));
        productList.add(new Product(R.drawable.ic_2, "美女1"));
        productList.add(new Product(R.drawable.ic_3, "美女1"));
        }

效果:

這裡寫圖片描述

效果還不錯:<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L3A+DQo8aDIgaWQ9"添加分割欄">添加分割欄:

大家都知道ItemDecoration 用於給每個item添加間隔的。
寫一個SpacesItemDecoration 類繼承 RecyclerView.ItemDecoration

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.left = space;
        outRect.right = space;
        outRect.bottom = space;
        if (parent.getChildAdapterPosition(view) == 0) {
            outRect.top = space;
        }
    }
}

間隔默認是透明的
這是原作者寫的,繼承後只重寫了getItemOffsets一個方法,通過導入space的數值設置邊框的大小,並判斷是否是頂部的。

Activity引用:
添加在onCreate()裡面:

//設置item之間的間隔
        SpacesItemDecoration decoration = new SpacesItemDecoration(100);
        recyclerView.addItemDecoration(decoration);

為了查看明顯,設置的間隔比較大。
這裡寫圖片描述

是不是圖片變小了,是因為間隔的原因。
添加特效邊框:
來自鴻洋的博客。

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;

    public DividerGridItemDecoration(Context context) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        //橫線有效
        drawHorizontal(c, parent);
        //豎線無效
        drawVertical(c, parent);

    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin
                    + mDivider.getIntrinsicWidth();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();

        // 在每一個子控件的右側畫線
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            int right = child.getRight() - child.getPaddingRight();
            int left = right - mDivider.getIntrinsicWidth();
            final int top = child.getTop() + child.getPaddingTop();
            final int bottom = child.getTop() + child.getHeight() - child.getPaddingBottom();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }


    //    @Override
//    public void getItemOffsets(Rect outRect, int itemPosition,
//                               RecyclerView parent) {
//        int spanCount = getSpanCount(parent);
//        int childCount = parent.getAdapter().getItemCount();
//        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最後一行,則不需要繪制底部
//        {
//            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
//        } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最後一列,則不需要繪制右邊
//        {
//            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
//        } else {
//            outRect.set(0, 0, mDivider.getIntrinsicWidth(),
//                    mDivider.getIntrinsicHeight());
//        }
//    }
// Item之間的留白
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
    }
}

這裡使用了系統的styles 所以可以在文件裡修改樣式。詳見基礎文章。

這裡寫圖片描述

這裡只顯示了底下的邊框。左右邊框沒有畫出來。沒有解決。

添加刪除動畫

見基礎文章

點擊事件和長按事件

見基礎文章

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved