Виджет RecyclerView — простой пример


Рассмотрим пример построения списка с помощью относительно нового виджета RecyclerView. Виджет RecyclerView рекомендуется использовать для достаточно больших списков, т.к. его код позволяет формировать и отображать списки значительно эффективнее и производительнее.

Виджет RecyclerView

Итак, приступим. Первое, что мы сделаем — это добавим нужные зависимости для gradle:

compile 'com.android.support:recyclerview-v7:21.0.+'

Нужная секция в файлике у меня выглядит так:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:20.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

Создадим layout для главного активити с вложенным виджетом RecyclerView — res/layout/activity_main.xml:

<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=".MainActivity">

    <!-- A RecyclerView with some commonly used attributes -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

Добавим разметку для отдельного пункта списка res/layout/recycler_item.xml:

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

    <TextView
        android:id="@+id/tv_recycler_item"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="7dp"
        android:textSize="18sp" />

</LinearLayout>

Как вы уже поняли — отдельный пункт у нас состоит из одного TextView.

Создадим класс адаптера RecyclerAdapter, который будет наследоваться от RecyclerView.Adapter<RecyclerAdapter.ViewHolder>:

package ru.androiddocs.recyclerview;

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


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

    private String[] mDataset;

    // класс view holder-а с помощью которого мы получаем ссылку на каждый элемент
    // отдельного пункта списка
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // наш пункт состоит только из одного TextView
        public TextView mTextView;

        public ViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(R.id.tv_recycler_item);
        }
    }

    // Конструктор
    public RecyclerAdapter(String[] dataset) {
        mDataset = dataset;
    }

    // Создает новые views (вызывается layout manager-ом)
    @Override
    public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_item, parent, false);

        // тут можно программно менять атрибуты лэйаута (size, margins, paddings и др.)

        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Заменяет контент отдельного view (вызывается layout manager-ом)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.mTextView.setText(mDataset[position]);

    }

    // Возвращает размер данных (вызывается layout manager-ом)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

Я постарался добавить комментарии для каждого метода, чтобы было понятнее, для чего они используются и какова их роль. Если отдельный пункт вашего списка имеет несколько составных элементов (т.е. не только TextView), то нужно добавить инициализацию этих элементов во внутренний класс ViewHolder. Контент для каждого списка мы сеттим в методе onBindViewHolder().

Создаем класс Активити — MainActivity.java

package ru.androiddocs.recyclerview;

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


public class MainActivity extends ActionBarActivity {

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] myDataset = getDataSet();

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // если мы уверены, что изменения в контенте не изменят размер layout-а RecyclerView
        // передаем параметр true - это увеличивает производительность
        mRecyclerView.setHasFixedSize(true);

        // используем linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        // создаем адаптер
        mAdapter = new RecyclerAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }


    private String[] getDataSet() {

        String[] mDataSet = new String[100];
        for (int i = 0; i < 100; i++) {
            mDataSet[i] = "item" + i;
        }
        return mDataSet;
    }

}

В методе onCreate() мы инициализируем наше виджет RecyclerView и RecyclerAdapter, передавая последнему массив строковых данных. Данные получаем из метода getDataSet().

один комментарий на “Виджет RecyclerView — простой пример

  1. maxim_bo

    Почем дата сет массив используется?
    Как в него получить данные из БД?

    Reply

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*