前面安卓日記——玩轉(zhuǎn)Material Design(伸縮頂部篇)提到要想用頂部伸縮必須要RecyclerView的配合,今天就給大家介紹一下RecyclerView的用法,順帶介紹一下CardView
RecyclerView是一種流式布局,所用的Adapter要求強(qiáng)制使用ViewHolder
這個RecyclerView比傳統(tǒng)的流式布局更加自由,當(dāng)然要寫的東西也只是多那么一點而已
1.導(dǎo)入所需的包
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:appcompat-v7:23.4.0'
2.編輯主layout
<?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.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
2.編輯RecyclerView的Item
新建一個layout(我取名為item_recycler)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="5dp"
app:cardElevation="5dp"
android:layout_margin="10dp">
<ImageView
android:id="@+id/ivPic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"/>
</android.support.v7.widget.CardView>
使用CardView作為主布局,把邊角弧度設(shè)為5dp,提升高度設(shè)為5dp
CardView就是這么簡單
3.編輯一個Adapter
這個Adapter必須繼承自RecyclerView.Adapter垫卤,而且要在這個Adapter新建一個繼承自RecyclerView.ViewHolder的內(nèi)部類
然后要在構(gòu)造方法里傳入數(shù)據(jù)
總的Adapter如下
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecVH> {
List<Product> products=new ArrayList<Product>();
//構(gòu)造方法傳入數(shù)據(jù)
public RecyclerAdapter(List<Product>products){
this.products=products;
}
//創(chuàng)造ViewHolder
@Override
public RecVH onCreateViewHolder(ViewGroup parent, int viewType) {
//把item的Layout轉(zhuǎn)化成View傳給ViewHolder
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler,parent,false);
return new RecVH(view);
}
// 將數(shù)據(jù)放入相應(yīng)的位置
@Override
public void onBindViewHolder(RecVH holder, int position) {
holder.tvTitle.setText(products.get(position).getTitle());
holder.ivPic.setImageResource(products.get(position).getImg());
}
@Override
public int getItemCount() {
return products.size();
}
//ViewHolder綁定控件
public class RecVH extends RecyclerView.ViewHolder{
ImageView ivPic;
TextView tvTitle;
public RecVH(View itemView) {
super(itemView);
ivPic= (ImageView) itemView.findViewById(R.id.ivPic);
tvTitle= (TextView) itemView.findViewById(R.id.tvTitle);
}
}
}
4.編輯界面邏輯代碼
public class RecyclerActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Product>products=new ArrayList<Product>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
initVar();
initView();
}
private void initView() {
recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
//設(shè)置并列2行的layoutManager
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
// 設(shè)置線性布局的layoutManager
// LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
// recyclerView.setLayoutManager(linearLayoutManager);
//設(shè)置adapter
RecyclerAdapter adapter=new RecyclerAdapter(products);
recyclerView.setAdapter(adapter);
}
//新建一些數(shù)據(jù)
private void initVar() {
products.add(new Product(R.drawable.avastar,"hello"));
products.add(new Product(R.drawable.avastar,"hello"));
products.add(new Product(R.drawable.logo,"hello"));
products.add(new Product(R.drawable.avastar,"hello"));
products.add(new Product(R.drawable.iconfont_source,"hello"));
products.add(new Product(R.drawable.iconfont_about,"hello"));
products.add(new Product(R.drawable.iconfont_source,"hello"));
products.add(new Product(R.drawable.avastar,"hello"));
}
}
我這里用的是兩行并列顯示的形式,如果想像listView一樣的話就可以把RecyclerView的LayoutManager 設(shè)為LinearLayoutManager 出牧,就是上面代碼注釋掉那一塊
一個瀑布流的RecyclerView就大功告成了
把RecyclerView嵌入到篇博客相應(yīng)的位置就好了
最終效果
其實RecyclerView還有一個玩法就是我想在RecyclerView頂部弄一個不同樣式的布局怎么辦呢穴肘?也就是說頂部item的layout不一樣怎么辦呢?就像我上篇博客的效果那樣舔痕,頂部不一樣
強(qiáng)大的RecyclerView當(dāng)然也提供了解決方案
細(xì)心的網(wǎng)友會發(fā)現(xiàn)onCreateViewHolder方法里有個參數(shù)名為viewType
那怎么傳入viewType评抚,從而生成不同的ViewHolder呢?
只需重寫getItemViewType方法就好了
@Override
public int getItemViewType(int position) {
return position;
}
表示我傳入的viewType和position一樣伯复,新建ViewHolder時判斷viewType如果是0的話就新建不同的View慨代,并且把這個viewType傳到ViewHolder的構(gòu)造方法里,這樣才能根據(jù)不同的位置使用不用的view綁定不同控件
還要注意的是這時總的item數(shù)就等于傳入的List的Size+1,還有List中數(shù)據(jù)的位置也是比實際item的位置-1的啸如。
以另外一個上一篇博客所使用到的Adapter為例
傳入List還有頂部的數(shù)據(jù)
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.MyViewHolder> {
List<String> mListData;
public ListAdapter(List<String> mListData) {
this.mListData = mListData;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view;
if (viewType==0){
view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_top,
viewGroup, false);
}else {
view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item,
viewGroup, false);
}
return new MyViewHolder(view,viewType);
}
@Override
public void onBindViewHolder(MyViewHolder myViewHolder, int viewType) {
if (viewType!=0){
myViewHolder.title.setText(mListData.get(viewType-1));
}else {
myViewHolder.tvFoucusedNum.setText("100");
myViewHolder.tvFocusNum.setText("200");
}
}
//item數(shù)量是List的Size+1
@Override
public int getItemCount() {
return mListData == null ? 0 : mListData.size()+1;
}
@Override
public int getItemViewType(int position) {
return position;
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
TextView tvFocusNum;
TextView tvFoucusedNum;
public MyViewHolder(View itemView,int i) {
super(itemView);
if (i==0){
tvFocusNum= (TextView) itemView.findViewById(R.id.tvFocusNum);
tvFoucusedNum= (TextView) itemView.findViewById(R.id.tvFocusedNum);
}else {
title = (TextView) itemView.findViewById(R.id.listitem_name);
}
}
}
}
這樣子就可以區(qū)分開頂部啦侍匙。
好了關(guān)于Material Design的控件使用就介紹到這里,還有一些比較常用的控件也值得去玩的叮雳,我就不再介紹了想暗。