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:+'
爲了簡單直接上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>
<?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 :下載地址
最後效果圖