Android Recyclerview 簡單實用 瀑布流等方式,並加入上下拉加載

RecyclerView 已經出現有一年多了,看過的和沒看過的都須要瞭解一下。html


據官方的介紹,該控件用於在有限的窗口中展現大量數據集,其實這樣功能的控件咱們並不陌生,例如:ListView、GridView。java


使用RecyclerView取代以往使用的ListView、GridView,使用SwipeRefreshLayout取代pull-to-refresh第三方庫,打造更符合Material Design風格的APP。
android


開始以前,咱們須要先導入這個。git


Android Studio 在build 中加入github

compile 'com.android.support:recyclerview-v7:+'

Eclipse 直接導入support-v7就能夠了。


爲了簡單直接上Demo 代碼:dom

首先上layout 佈局文件:ide


因爲須要用到下拉刷新,爲了簡單仍是使用官方的組件:佈局

android.support.v4.widget.SwipeRefreshLayout

<?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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.recyclerview.demo.MainActivity">

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/swiperefresh_layout"
        >
        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycler_view"
            ></android.support.v7.widget.RecyclerView>
    </android.support.v4.widget.SwipeRefreshLayout>

</RelativeLayout>

那麼接下來就須要編寫ITEM了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/photo_item_img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"/>
    <TextView
        android:id="@+id/photo_item_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"/>
</LinearLayout>




OK,既然作瀑布流,最流行的的那就是圖片瀑布了。 咱們先從Windows 中拷貝幾張圖片到項目中去。post


完成這步,那就能夠着手編寫代碼了。ui

和ListView 同樣,既然使用相對複雜的東西,那麼就須要重寫適配器。 這裏先不考慮他的點擊事件。後面教程將會說到點擊事件

public class MyAdapter extends RecyclerView.Adapter<PhotoView> {
    //定義數據模型
    private List<Photo> products;

    private MyItemClickListener mItemClickListener;

    //構造方法
    public MyAdapter(List<Photo> list) {
        products=list;
    }
    /**
     * 設置Item點擊監聽
     * @param listener
     */
    public void setOnItemClickListener(MyItemClickListener listener){
        this.mItemClickListener = listener;
    }
    //建立每一條小牧
    @Override
    public PhotoView onCreateViewHolder(ViewGroup viewGroup, int i) {
        //加載佈局
        View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.photo_item, viewGroup, false);

        return new PhotoView(view,mItemClickListener);
    }
    //banding數據的數據模型
    @Override
    public void onBindViewHolder(final PhotoView photoView, int position) {

        photoView.imageView.setImageResource(products.get(position).getImage());

        photoView.titleView.setText(products.get(position).getTitle());
    }
    //獲取數據的大小
    @Override
    public int getItemCount() {
        return products.size();
    }
    //增長一項
    public void addData(int position,Photo photo) {
        products.add(position,photo);
        notifyItemInserted(position);
    }


    //刪除一項
    public void removeData(int position) {
        products.remove(position);
        notifyItemRemoved(position);
    }
}


嗶嗶

再繼續將實體類型添加進去,讓適配器與實體進行斷定。因爲是模擬數據,那麼咱們就用本地的圖片代替。因此實體爲int 的圖片ID


public class Photo {
    private int image;

    private String title;

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getTitle() {
        return title;
    }

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

    public Photo(int image, String title) {
        this.image = image;
        this.title = title;
    }
}

OK,編寫到這裏,那麼咱們須要思考的是如何去實現這個瀑布的效果。


Recyclerview  提供了三個佈局管理器。

LinearLayoutManager 水平或者垂直的Item視圖。

GridLayoutManager 網格Item視圖。

StaggeredGridLayoutManager 交錯的網格Item視圖。


這三個佈局管理能夠根據業務需求的不一樣設置不一樣的管理器,這裏咱們將使用

StaggeredGridLayoutManager 來實現 瀑布流的效果
 。


public class MainActivity extends AppCompatActivity {

    private final int[] imageRes = new int []{
        R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4,R.drawable.p5,R.drawable.p6,R.drawable.p7,R.drawable.p8
    };

    private MyAdapter myAdapter;

    private SwipeRefreshLayout mSwipeRefreshLayout;

    private RecyclerView recyclerView;

    private StaggeredGridLayoutManager mStaggerdGridLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView= (RecyclerView) findViewById(R.id.recycler_view);

        mStaggerdGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        //設置layoutManager
        recyclerView.setLayoutManager(mStaggerdGridLayoutManager);

        myAdapter = new MyAdapter(new ArrayList<Photo>());

        recyclerView.setAdapter(myAdapter);
        //設置item之間的間隔
        SpacesItemDecoration decoration=new SpacesItemDecoration(2);

        recyclerView.addItemDecoration(decoration);

        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh_layout);

        mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE);

        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //  new MoreArticleTask().execute(mAdapter.getTopArticleId());
                Toast.makeText(getApplicationContext(),"刷新",Toast.LENGTH_SHORT).show();
                for(int i = 0 ; i < myAdapter.getItemCount() ;i ++) {
                    myAdapter.removeData(i);
                }
                refreshing();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });
        mSwipeRefreshLayout.post(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(true);
                refreshing();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });
    }

    //用於刷新的方法  主要使用適配器中addData 方法
    private void refreshing(){
        for(int i = 0 ; i < imageRes.length; i++){
            Photo photo = new Photo(imageRes[(int)(Math.random()*imageRes.length)],"這是第"+(int)(Math.random()*imageRes.length)+":"+i+"張圖片");
            myAdapter.addData(i,photo);
        }
    }

    private void loadMore(){

    }
}

其中咱們爲了實現 瀑布流的須要設置下劃線 也就是空隙:


//設置item之間的間隔
        SpacesItemDecoration decoration=new SpacesItemDecoration(2);

        recyclerView.addItemDecoration(decoration);

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

OK ,那麼實現線性佈局 能夠直接這樣寫

//設置layoutManager

recyclerView.setLayoutManager(<span class="crayon-r">new</span><span class="crayon-h"> </span><span class="crayon-e">LinearLayoutManager</span><span class="crayon-sy">(</span><span class="crayon-r">this</span><span class="crayon-sy">)</span><span class="crayon-sy"></span>);

Demo :下載地址

點擊打開連接

最後效果圖

相關文章
相關標籤/搜索