RecyclerView 基本使用

原文首发 http://blog.lll0.net/post/recyclerview.html

强大而高效的 RecyclerView

ListView作为一个强大而有使用频繁的控件,但是随着我们业务的发展慢慢的就感觉 ListView 在某些业务场景中已经不能满足我们的业务需求。举个栗子:如果我们在一个页面上需要加载不同的布局,在列表中间某一行加载一个广告试图,而这个广告的布局和整个个列表的布局样式是完全不一样的。如果放在ListView 中,这种布局是不太好实现的。但是放在Google 提出的新控件 ReyclerView 中 实现这种布局是非常简单的。

RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好。

基本介绍

在使用RecyclerView中引入了几个相关的类

  1. LayoutManager 用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个View的时候,LayoutManager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的View和频繁的调用findViewById方法(与ListView原理类似)。Google 为我们提供了 几个基础的布局
    1. LinearLayoutManager 线性布局布局样式和ListView一样 呈现的是线性
    2. GridLayoutManager 表格布局与GridView 一样
    3. StaggeredGridLayoutManager 瀑布流布局 这是新的布局 简单描述就是加载的每个item在页面上占有的空间都是不一样的布局
  2. RecyclerView.Adapter RecyclerView 的适配器 数据的加载和item 的绑定都是通过这个类来实现。在使用的时候需要继承该类来进行相应的处理
  3. RecyclerView.ViewHolder 同样是使用中需要继承该类,然后进行把数据和item里面的布局进行绑定

在使用的时候 其实不用考虑复用的问题。

简单使用

1.添加依赖在build.gradle 中添加依赖 ,然后同步一下 引入依赖需要的包

dependencies {
     compile 'com.android.support:recyclerview-v7:25.1.1' 
}

2.布局中使用RecylerView

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.lll0.bus.ui.test_activity.RecyclerViewTestActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="368dp"
        android:layout_height="551dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp" />
</android.support.constraint.ConstraintLayout>

3.创建布局之后需要在Activity中获得这个控件,并声明LayoutManagerAdapter,代码如下

 mRecycler = (RecyclerView) findViewById(R.id.recycler);
 mRecycler.setLayoutManager(new LinearLayoutManager(mActitivity));
 recyclerViewAdapter = new RecyclerViewAdapter(beans,mActitivity);
 mRecycler.setAdapter(recyclerViewAdapter);

4.Adapter的创建

package net.lll0.bus.adapter.test;

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

import net.lll0.bus.suzhoubus.R;
import net.lll0.bus.adapter.RecyclerViewHolder;

import java.util.List;

/**
 * Created by liang on 2017/8/24.
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    private String typeView01 = "item1";
    private String typeView02 = "item2";
    /**
     * 加载不同的两种方式
     * 1. 传入不同的数据源,对应的位置加载不同的布局
     * 2. 传入一个数据源,但是通过数据源里面特殊的字段判断加载什么布局
     */
    private List<Bean> bean;
    private Context mContext;
    public RecyclerViewAdapter(List<Bean> bean, Context mContext) {
        this.bean = bean;
        this.mContext = mContext;
    }
    @Override
    public int getItemViewType(int position) {
        //通过这个区分加载不同 view
        //通过判断特殊的字段加载不同的布局

        return bean.get(position).type;
    }
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //通过 getTtemViewType 返回的 内容加载不同 的布局

        //假设加载 三中布局分别对应 1 2 3

        if (1 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item, parent, false), viewType);
        } else if (2 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item_lineinfo, parent, false), viewType);
        } else if (3 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.nav_header_home, parent, false), viewType);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        //onCreateViewHolder 为不同的布局绑定对应的数据
        Bean bean = this.bean.get(position);
        int type = bean.type;
        if (1 == type) {
            holder.setText(R.id.textView2,"textView2");
            holder.setText(R.id.textView3,"textView3");
        } else if (2 == type) {
            holder.setText(R.id.lineinfo_index,position+"");
        } else if (3 == type) {
        }
    }
    @Override
    public int getItemCount() {
        //主要是计算 加载数据的总数
        return bean.size();
    }
}

5.RecyclerView.ViewHolder 子类的实现 ,这是一个通用的ViewHolder

package net.lll0.bus.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
/**
 * Created by liang on 2016/2/15.
 */
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
    private SparseArray<View> mViews;//集合类,layout里包含的View,以view的id作为key,value是view对象
    private Context mContext;//上下文对象
    private int type;

    public RecyclerViewHolder(Context ctx, View itemView) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
    }
    public RecyclerViewHolder(Context ctx, View itemView,int type) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
        this.type = type;
    }
    public View getItemView() {
        return itemView;
    }
    /*
     * 通过空间id在SparseArray集合中找出用户View
     * @param viewId  控件的id
     * @param <T>  具体的是那个控件
     * @return  当然是返回你要找的控件了
     */
    private <T extends View> T findViewById(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }
    /**
     * 通过findViewById以及控件id的到用户的空间对象
     *
     * @param viewId
     * @return
     */
    public View getView(int viewId) {
        return findViewById(viewId);
    }
    public TextView getTextView(int viewId) {
        return (TextView) getView(viewId);
    }
    public Button getButton(int viewId) {
        return (Button) getView(viewId);
    }
    public ImageView getImageView(int viewId) {
        return (ImageView) getView(viewId);
    }
    public ImageButton getImageButton(int viewId) {
        return (ImageButton) getView(viewId);
    }
    public EditText getEditText(int viewId) {
        return (EditText) getView(viewId);
    }
    public RecyclerViewHolder setText(int viewId, String value) {
        TextView view = findViewById(viewId);
        view.setText(value);
        return this;
    }
    public RecyclerViewHolder setBackground(int viewId, int resId) {
        View view = findViewById(viewId);
        view.setBackgroundResource(resId);
        return this;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    /**
     * 通过该方法可以的到对应控件的点击事件
     *
     * @param viewId   控件的id
     * @param listener 需要实现的监听器
     * @return
     */
    public RecyclerViewHolder setClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        view.setOnClickListener(listener);
        return this;
    }
}

运行

只要实现以上代码,就能实现具体的内容。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,682评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,277评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,083评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,763评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,785评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,624评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,358评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,261评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,722评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,030评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,737评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,360评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,941评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,057评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,237评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,976评论 2 355

推荐阅读更多精彩内容