王学岗RecylerView(一)

RecyclerView是5.0新特性,是google为了替代ListView GridView这些组件,有自己的优点:耦合度很低的插件式组件;自己实现了convertView的重用,节省内存以及显示的速度
因为是5.0新特性,需要添加依赖
这里写图片描述
我就直接在代码里讲解了,代码注解很详细,可以看懂的
先看MaiActivity类:

package com.example.acer.wang_xue_gang_2016_6_5;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private List<String> data;
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //第一步:获取控件
        RecyclerView rl_RecylerView = (RecyclerView) findViewById(R.id.rl);
        //第二步:初始化数据
        initData();
        //第三部:设置适配器
        myAdapter = new MyAdapter(this, data);
        rl_RecylerView.setAdapter(myAdapter);
        //第四部:设置布局管理器,与ListView不同的地方——————线性布局管理器,垂直/水平grid布局管理器
        //设置线性布局管理器
        rl_RecylerView.setLayoutManager(new LinearLayoutManager(this));
       
        //第五步:添加分割线
        rl_RecylerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
    }

    public void initData() {
        data = new ArrayList<String>();
        for (int i = 0; i < 100; i++) {
            data.add("张欣爱我" + i + "生" + i + "世");
        }
    }
}

自定义的适配器

package com.example.acer.wang_xue_gang_2016_6_5;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * @author w_x_g
 * @time 2016/6/5 16:38
 * @note ${TODO}
 */
//泛型参事需要在类中定义
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private Context context;
    private LayoutInflater layoutInflater;
    private List<String> listData;

    public MyAdapter(Context context,  List<String> listData) {
        this.context = context;
        this.layoutInflater = LayoutInflater.from(context);
        this.listData = listData;
    }

    //创建ViewHolder缓存对象,将adapter_item布局渲染成view对象
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = layoutInflater.inflate(R.layout.adapter_item, parent, false);

        //返回值是内部类,需要一个View 的参数,该参数就是条目的view对象
        //把渲染的xml布局 交给MyViewHolder就实现了缓存,可以重复利用了
        return new MyViewHolder(view);
    }

    //将数据与view 绑定
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tv_item_textview.setText(listData.get(position));
    }

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

    //在这里实现了缓存,
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv_item_textview;

        public MyViewHolder(View itemView) {
            super(itemView);
            //拿到布局的控件,绑定数据的时候需要使用
            tv_item_textview = (TextView) itemView.findViewById(R.id.tv_item);
        }

    }
}

activity_main.xml文件和adapter_item.xml文件

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#123456"
        android:text="张欣"/>

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

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

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="赵云"
        />
</LinearLayout>

大家敲一遍代码会发现,他和我们前面讲的listview的优化有很多相似之处!
看下运行效果
这里写图片描述
大家会发现recylerview没有分割线,RecyclerView并没有divider这样的属性!要想设置分割线需要重新抽象类RecyclerView.ItemDecoration;android文档中有一个官方demo;我们可以借用一下。

import android.content.Context;  
import android.content.res.TypedArray;  
import android.graphics.Canvas;  
import android.graphics.Rect;  
import android.graphics.drawable.Drawable;  
import android.support.v7.widget.LinearLayoutManager;  
import android.support.v7.widget.RecyclerView;  
import android.view.View;  
  
/* 
这个是v7 中的一个sample中的 
 */  
public class DividerItemDecoration extends RecyclerView.ItemDecoration{  
  
    private static final int[] ATTRS = new int[]{  
            android.R.attr.listDivider  
    };  
  
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;  
  
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;  
  
    private Drawable mDivider;  
  
    private int mOrientation;  
  
    public DividerItemDecoration(Context context, int orientation) {  
    //获取listDivider属性,该属性可在sdk\platforms\android-23\data\res\values中找到
        final TypedArray a = context.obtainStyledAttributes(ATTRS);  
        mDivider = a.getDrawable(0);//系统属性中获取  
        //改成自己的图片
        //mDivider=context.getResource.getDrawable();
        a.recycle();  
        setOrientation(orientation);  
    }  
  
    public void setOrientation(int orientation) {  
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {  
            throw new IllegalArgumentException("invalid orientation");  
        }  
        mOrientation = orientation;  
    }  
  
    @Override //在RecyclerView的onDraw中执行  
    public void onDraw(Canvas c, RecyclerView parent) {  
        if (mOrientation == VERTICAL_LIST) {  
            drawVertical(c, parent);  
        } else {  
            drawHorizontal(c, parent);  
        }  
    }  
  
    /** 
     * 绘制纵向列表时的分隔线  这时分隔线是横着的 
     * 每次 left相同,top根据child变化,right相同,bottom也变化 
     * @param c 
     * @param parent 
     */  
    public void drawVertical(Canvas c, RecyclerView parent) {  
    //左内边距,条目的起始点。
        final int left = parent.getPaddingLeft();  
        final int right = parent.getWidth() - parent.getPaddingRight();  
  //根据不同的item设置不同的分割线
        final 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 top = child.getBottom() + params.bottomMargin;  
            final int bottom = top + mDivider.getIntrinsicHeight();  
            mDivider.setBounds(left, top, right, bottom);  
            mDivider.draw(c);  
        }  
    }  
  
    /** 
     * 绘制横向列表时的分隔线  这时分隔线是竖着的 
     * l、r 变化; t、b 不变 
     * @param c 
     * @param parent 
     */  
    public void drawHorizontal(Canvas c, RecyclerView parent) {  
        final int top = parent.getPaddingTop();  
        final int bottom = parent.getHeight() - parent.getPaddingBottom();  
  
        final 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.getRight() + params.rightMargin;  
            final int right = left + mDivider.getIntrinsicHeight();  
            mDivider.setBounds(left, top, right, bottom);  
            mDivider.draw(c);  
        }  
    }  
  
    @Override  //预留item间隙  RecyclerView各个item之间默认是没有间隙的,但是绘制分割线却需要间隙,默认情况下高度等于分//割//线图片的高度
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {  
        if (mOrientation == VERTICAL_LIST) {  
        //获取图片物理尺寸的高度
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
        } else {  
        //获取图片的实际宽度
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);  
        }  
    }  
}  

然后我们在MainActivity里折折分割线

 //第五步:添加分割线
rl_RecylerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
    }

看下效果
这里写图片描述
这样我们就有分割线了,但是我们也可以使用自己的图片做分割线,我们修改下 DividerItemDecoration的构造方法;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        // mDivider = a.getDrawable(0);//系统属性中获取,可以在这里修改分割线图片
        mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher);
        a.recycle();
        setOrientation(orientation);
    }

我们就是用系统自带的ic_launcher图片做分割线;看下效果
这里写图片描述
虽然分割线很丑,但好歹是我们自己的分割下了!
我们先定义一个R.drawable.divider_background文件

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle"
    >
    <size
        android:width="5dp"
        android:height="5dp"/>
    <gradient
        android:centerColor="#00ff00"
        android:endColor="#0000ff"
        android:startColor="#ff0000"/>
</shape>

修改res\values\styles.xml文件:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--自己定义listDivider,覆盖系统定义的-->
        <item name="android:listDivider">@drawable/divider_background</item>
    </style>

</resources>

使用自己定义的,覆盖系统自己定义的,我们看下运行效果
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值