Android Notes 之 RecyclerView 的使用

自己未解决的问题:CommonPullToRefresh的上拉加载可以上拉很大一段距离,等待下一阶段学习View的Scroll再来补充

本篇文章参考 http://blog.csdn.net/leejizhou/article/details/50670657
本篇内容:RecyclerView的单Item,多Item,添加Head和Foot

前戏

导入依赖
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:recyclerview-v7:24.0.0-alpha1'
    compile 'com.android.support:cardview-v7:24.0.0-alpha1'
}
引入RecyclerView布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical" tools:context="com.android.tongs.recyclerview2.MainActivity">

    <android.support.v7.widget.RecyclerView  android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

RecyclerView之单ItemView式布局

布局文件
简单的由ImageView和TextView组成

<?xml version="1.0" encoding="utf-8"?>
<!-- foreground 点击时有Ripple效果-->
<!-- cardElevation 高度以产生阴影效果-->
<!--CardView继承自FrameLayout-->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cv_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="6dp" android:foreground="?android:attr/selectableItemBackground" card_view:cardBackgroundColor="#795548" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp">

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">

        <ImageView  android:id="@+id/iv_pic" android:layout_height="210dp" android:layout_width="match_parent" android:scaleType="fitXY" />

        <TextView  android:id="@+id/tv_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:textColor="#ffffff" />
    </LinearLayout>
</android.support.v7.widget.CardView>

适配器的主要方法

/** * 这个方法主要是创建一个加载ItemView的ViewHolder */
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  //这里要添加的资源是cardView,parent是RecyclerView,不添加的话设置card的边距无效
 return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.rv_item,parent,false));
}


/** * 这个方法主要是获取ViewHolder中的控件并将数据源设置到控件上。 */
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    MyRecyclerViewAdapter.ViewHolder mHolder = (ViewHolder) holder;
    mHolder.image.setImageResource(pics[position]);
    mHolder.text.setText(titles[position]);
    mHolder.card.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {  Toast.makeText(context,titles[position],Toast.LENGTH_SHORT).show();
        }
    });
}
ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder{
        private ImageView image;
        private TextView text;
        private CardView card;
        public ViewHolder(View itemView) {
            super(itemView);
            card = (CardView) itemView.findViewById(R.id.cv_item);
            text = (TextView) card.findViewById(R.id.tv_text);
            image = (ImageView) card.findViewById(R.id.iv_pic);
        }
}
RecyclerView的三种布局

list:线性垂直布局
grid:网格布局
staggered:控件大小按实际大小排列的网格布局,类似瀑布流

if(type.equals("list")){
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        }else if(type.equals("grid")){
            mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));
        }else if(type.equals("staggered")){
            mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));
        }
        mRecyclerView.setAdapter(new MyRecyclerViewAdapter(this,title,pics));

RecyclerView之多ItemView式布局

多Item布局实际上就是在滑动时让适配器加载不同的布局
这里添加一个只有TextView的布局文件

<?xml version="1.0" encoding="utf-8"?>
<!-- foreground 点击时有Ripple效果-->
<!-- cardElevation 高度以产生阴影效果-->
<!--CardView继承自FrameLayout-->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cv_item2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="6dp" android:foreground="?android:attr/selectableItemBackground" card_view:cardBackgroundColor="#E040FB" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp">

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">

        <TextView  android:id="@+id/tv_text2" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:textColor="#ffffff" />
    </LinearLayout>

</android.support.v7.widget.CardView>

事先约定ItemView的type编号

/** * 设置两个枚举类型,以表示recyclerView的itemView的序号 * 通过ordinal获取枚举数据的序号 */
public enum ITEM_TYPE{
    ITEM0,ITEM1
}

适配器添加的方法
适配器是通过ViewHolder来加载布局的,因此还要创建一个ViewHolder,适配器在创建的时候会回调getItemType方法来获取ItemView的type类型,以创建对应的ViewHolder

 /** * 根据约定的ItemType编号,在适当的position返回你想要的type */
 @Override
  public int getItemViewType(int position) {
      return position % 2 == 0 ? ITEM_TYPE.ITEM0.ordinal() :ITEM_TYPE.ITEM1.ordinal();

/** * 根据viewType加载不同的itemView */
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     if(viewType==ITEM_TYPE.ITEM0.ordinal()) {
         return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.rv_item, parent, false));
     }else if(viewType==ITEM_TYPE.ITEM1.ordinal()){
         return new ViewHolder2(LayoutInflater.from(context).inflate(R.layout.rv_item2, parent, false));
     }
     return null;
 }

/** * itemview2的holder */
public class ViewHolder2 extends RecyclerView.ViewHolder{
    private TextView text;
    private CardView card;
    public ViewHolder2(View itemView) {
        super(itemView);
        card = (CardView) itemView.findViewById(R.id.cv_item2);
        text = (TextView) card.findViewById(R.id.tv_text2);
    }
}

RecyclerView之添加Head和Foot

添加Head和Foot实际上就是添加Head和Foot两个ItemView而已,这里为了简单起见,Head和Foot都采用简单的TextView的布局即可。

<?xml version="1.0" encoding="utf-8"?>
<!-- foreground 点击时有Ripple效果-->
<!-- cardElevation 高度以产生阴影效果-->
<!--CardView继承自FrameLayout-->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cv_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="6dp" android:foreground="?android:attr/selectableItemBackground" card_view:cardBackgroundColor="#ffff00" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp">
    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">

        <TextView  android:id="@+id/head" android:layout_width="match_parent" android:layout_height="100dp" android:text="Header" android:textSize="32sp" android:padding="20dp" />
    </LinearLayout>
</android.support.v7.widget.CardView>

接下来的步骤和多ItemView一致,根据ViewType来创建ViewHolder,加载不同的布局文件。

只是对于GridLayoutManager要将head和foot的span设置为match_parent

GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2);
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return position==0||position==title.length+1?gridLayoutManager.getSpanCount():1;
                }
            });
mRecyclerView.setLayoutManager(gridLayoutManager);

本文纯属个人笔记,表达的也就自己能理解,不理解的同学,源代码都可以在https://github.com/tongsdroid/LearnAndroid的RecyclerView分支中下载到。

你可能感兴趣的:(UI,android)