Статьи

Начало работы с RecyclerView и CardView на Android

Если вы заинтересованы в создании приложения для Android, в котором для отображения данных используются списки, в Android Lollipop есть два новых виджета, облегчающих вашу жизнь: RecyclerView и CardView . Используя эти виджеты, вы легко сможете придать своему приложению внешний вид, соответствующий принципам, указанным в спецификации дизайна материалов Google.

Отличное место для начала при создании приложения — использовать шаблон приложения для Android . Вы можете найти сотни из них на Envato Market, для создания всего, от приложения для обмена музыкой до веселой игры в обход препятствий .

Или вы можете попробовать этот универсальный шаблон приложения для Android , который дает вам прочную основу для создания практически любого типа приложения.

Шаблон универсального приложения для Android
Шаблон универсального приложения для Android на Envato Market

Чтобы следовать, вы должны использовать последнюю версию Android Studio. Вы можете получить его с сайта Android Developer .

На момент написания этой статьи менее 2% устройств Android работали с Android Lollipop. Однако благодаря библиотеке поддержки v7 вы можете использовать виджеты RecyclerView и CardView на устройствах с более ранними версиями Android, добавив следующие строки в раздел зависимостей в файле build.grade вашего проекта:

1
2
compile ‘com.android.support:cardview-v7:21.0.+’
compile ‘com.android.support:recyclerview-v7:21.0.+’

CardView — это ViewGroup . Как и любая другая ViewGroup , она может быть добавлена ​​в вашу Activity или Fragment с использованием XML-файла макета.

Чтобы создать пустой CardView , вам необходимо добавить следующий код в XML-код макета, как показано в следующем фрагменте:

1
2
3
4
5
6
<android.support.v7.widget.CardView
        xmlns:card_view=»http://schemas.android.com/apk/res-auto»
        android:layout_width=»match_parent»
        android:layout_height=»wrap_content»>
 
</android.support.v7.widget.CardView>

В качестве более реалистичного примера, давайте теперь создадим LinearLayout и CardView в него CardView . CardView может представлять, например, человека и содержать следующее:

  • TextView для отображения имени человека
  • TextView для отображения возраста человека
  • ImageView для отображения фотографии человека

Вот как будет выглядеть XML:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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:padding=»16dp»
    >
 
    <android.support.v7.widget.CardView
        android:layout_width=»match_parent»
        android:layout_height=»wrap_content»
        android:id=»@+id/cv»
        >
 
        <RelativeLayout
            android:layout_width=»match_parent»
            android:layout_height=»wrap_content»
            android:padding=»16dp»
            >
 
            <ImageView
                android:layout_width=»wrap_content»
                android:layout_height=»wrap_content»
                android:id=»@+id/person_photo»
                android:layout_alignParentLeft=»true»
                android:layout_alignParentTop=»true»
                android:layout_marginRight=»16dp»
                />
 
            <TextView
                android:layout_width=»wrap_content»
                android:layout_height=»wrap_content»
                android:id=»@+id/person_name»
                android:layout_toRightOf=»@+id/person_photo»
                android:layout_alignParentTop=»true»
                android:textSize=»30sp»
                />
 
            <TextView
                android:layout_width=»wrap_content»
                android:layout_height=»wrap_content»
                android:id=»@+id/person_age»
                android:layout_toRightOf=»@+id/person_photo»
                android:layout_below=»@+id/person_name»
                />
 
        </RelativeLayout>
 
    </android.support.v7.widget.CardView>
 
</LinearLayout>

Если этот XML-файл используется в качестве макета Activity , а для полей TextView и ImageView установлены значимые значения, то он будет отображаться на устройстве Android:

Автономная карта

Использование экземпляра RecyclerView немного сложнее. Однако определить его в XML-файле макета довольно просто. Вы можете определить его в макете следующим образом:

1
2
3
4
5
<android.support.v7.widget.RecyclerView
   android:layout_width=»match_parent»
   android:layout_height=»match_parent»
   android:id=»@+id/rv»
   />

Чтобы получить справку об этом в своей Activity , используйте следующий фрагмент:

1
RecyclerView rv = (RecyclerView)findViewById(R.id.rv);

Если вы уверены, что размер RecyclerView не изменится, вы можете добавить следующее для повышения производительности:

1
rv.setHasFixedSize(true);

В отличие от ListView , RecyclerView необходим LayoutManager для управления позиционированием его элементов. Вы можете определить свой собственный LayoutManager , расширив класс RecyclerView.LayoutManager . Однако в большинстве случаев вы можете просто использовать один из предопределенных подклассов LayoutManager :

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

В этом уроке я собираюсь использовать LinearLayoutManager . Этот подкласс LayoutManager по умолчанию сделает ваш RecyclerView похожим на ListView .

1
2
LinearLayoutManager llm = new LinearLayoutManager(context);
rv.setLayoutManager(llm);

Как и ListView , для RecyclerView необходим адаптер для доступа к его данным. Но прежде чем мы создадим адаптер, давайте создадим данные, с которыми мы можем работать. Создайте простой класс для представления лица, а затем напишите метод для инициализации объектов List of Person :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Person {
    String name;
    String age;
    int photoId;
 
    Person(String name, String age, int photoId) {
        this.name = name;
        this.age = age;
        this.photoId = photoId;
    }
}
 
private List<Person> persons;
 
// This method creates an ArrayList that has three Person objects
// Checkout the project associated with this tutorial on Github if
// you want to use the same images.
private void initializeData(){
    persons = new ArrayList<>();
    persons.add(new Person(«Emma Wilson», «23 years old», R.drawable.emma));
    persons.add(new Person(«Lavery Maiss», «25 years old», R.drawable.lavery));
    persons.add(new Person(«Lillie Watts», «35 years old», R.drawable.lillie));
}

Чтобы создать адаптер, который может использовать RecyclerView , вы должны расширить RecyclerView.Adapter . Этот адаптер следует шаблону дизайна держателя вида , что означает, что вы должны определить пользовательский класс, который расширяет RecyclerView.ViewHolder . Этот шаблон минимизирует количество вызовов дорогостоящего метода findViewById .

Ранее в этом уроке мы уже определили макет XML для CardView который представляет человека. Мы собираемся использовать этот макет сейчас. Внутри конструктора нашего пользовательского ViewHolder инициализируйте представления, принадлежащие элементам нашего RecyclerView .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{
 
    public static class PersonViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView personName;
        TextView personAge;
        ImageView personPhoto;
 
        PersonViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.cv);
            personName = (TextView)itemView.findViewById(R.id.person_name);
            personAge = (TextView)itemView.findViewById(R.id.person_age);
            personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
        }
    }
 
}

Затем добавьте конструктор в пользовательский адаптер, чтобы он имел дескриптор данных, отображаемых в RecyclerView . Поскольку наши данные представлены в форме объектов List of Person , используйте следующий код:

1
2
3
4
5
List<Person> persons;
 
RVAdapter(List<Person> persons){
    this.persons = persons;
}

RecyclerView.Adapter имеет три абстрактных метода, которые мы должны переопределить. Давайте начнем с метода getItemCount . Это должно вернуть количество элементов, присутствующих в данных. Поскольку наши данные представлены в виде List , нам нужно только вызвать метод size объекта List :

1
2
3
4
@Override
public int getItemCount() {
    return persons.size();
}

Затем переопределите метод onCreateViewHolder . Как следует из названия, этот метод вызывается, когда пользовательский ViewHolder должен быть инициализирован. Мы указываем макет, который должен использовать каждый элемент RecyclerView . Это делается путем раздувания макета с использованием LayoutInflater , передавая выходные данные в конструктор пользовательского ViewHolder .

1
2
3
4
5
6
@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
    PersonViewHolder pvh = new PersonViewHolder(v);
    return pvh;
}

Переопределите onBindViewHolder чтобы указать содержимое каждого элемента RecyclerView . Этот метод очень похож на метод getView адаптера ListView . В нашем примере, здесь вы должны установить значения полей name, age и photo в CardView .

1
2
3
4
5
6
@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
    personViewHolder.personName.setText(persons.get(i).name);
    personViewHolder.personAge.setText(persons.get(i).age);
    personViewHolder.personPhoto.setImageResource(persons.get(i).photoId);
}

Наконец, вам нужно переопределить метод onAttachedToRecyclerView . Сейчас мы можем просто использовать реализацию этого метода в суперклассе, как показано ниже.

1
2
3
4
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

Теперь, когда адаптер готов, добавьте следующий код в Activity для инициализации и использования адаптера, вызвав конструктор адаптера и метод setAdapter в RecyclerView :

1
2
RVAdapter adapter = new RVAdapter(persons);
rv.setAdapter(adapter);

При запуске примера RecyclerView на устройстве Android вы должны увидеть нечто похожее на следующий результат.

Из этого руководства вы узнали, как использовать виджеты CardView и RecyclerView , представленные в Android Lollipop. Вы также видели примеры использования этих виджетов в приложениях Material Design. Обратите внимание, что, хотя RecyclerView может делать почти все, что может ListView , для небольших наборов данных использование ListView все еще предпочтительнее, так как для него требуется меньше строк кода.

Вы можете обратиться к Справочнику разработчиков Android за дополнительной информацией о CardView и RecyclerView .

И если вы хотите ускорить разработку приложений, не забудьте проверить эти шаблоны приложений для Android на Envato Market.