RecyclerView
RecyclerView — это расширенная версия ListView с некоторыми улучшениями в производительности и с новыми функциями. Как следует из названия, RecyclerView перерабатывает или повторно использует представления элементов при прокрутке. В RecyclerView гораздо проще добавлять анимации по сравнению с ListView. В этом уроке мы разберем, как создать RecyclerView с заголовком, футером, разбиением на страницы и анимацией.
Настройка Gradle
Добавьте следующую зависимость в файл build.gradle:
//пожалуйста, проверьте последнюю версию
compile 'com.android.support:recyclerview-v7:23.1.1'
Добавление RecyclerView в XML представление
После того, как проект будет синхронизирован, добавьте компонент RecyclerView в ваш макет:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleView"
android:clipToPadding="false"
android:padding="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
Привязка XML с классом JAVA
Теперь в методе onCreate вашей активности добавьте следующий код:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setcontentview и ваше прочий код
mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
// Установите true, если ваш RecyclerView ограничен и имеет фиксированный размер
mRecyclerView.setHasFixedSize(false);
// Установите требуемый LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// Инициализирование и установка адаптера в RecyclerView
mAdapter = new MyAdapter(mList);
mRecyclerView.setAdapter(mAdapter);
}
Прежде чем идти дальше, давайте подробно рассмотрим приведенный выше код
- Layout Manager — Простыми словами, Layout Manager помогает нам определить структуру нашего RecyclerView. Есть три встроенных Layout Managers. Помимо этого, мы можем создать собственный пользовательский Layout Manager, чтобы удовлетворить наши требования.
- LinearLayoutManager показывает элементы в списке с вертикальной или горизонтальной прокруткой.
- GridLayoutManager показывает элементы в сетке.
- StaggeredGridLayoutManager показывает элементы в шахматной сетке.
- setHasFixedSize — Установите значение true, если вы не изменяете высоту или ширину у RecyclerView.
- RecyclerView Adapter — RecyclerView требует адаптер заполнения и управления элементами. Здесь мы передаем ArrayList со значениями в Adapter. Подробное описание адаптера в следующем разделе.
RecyclerView ItemDecoration
ItemDecoration позволяет приложению добавлять специальный полосы и смещения к определенным представлениям элементов из набора данных адаптера. Это может быть полезно для рисования разделителей между элементами, выделениями, границами визуальной группировки и т. д. – developer.android.com
В этом примере мы будем использовать ItemDecoration для добавления отступов к каждому элементу.
public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
private int offset;
public ItemOffsetDecoration(int offset) {
this.offset = offset;
}
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
// Добавление отступов к нулевому элементу
if (parent.getChildAdapterPosition(view) == 0) {
outRect.right = offset;
outRect.left = offset;
outRect.top = offset;
outRect.bottom = offset;
}
}
}
}
В вышеприведенном классе мы устанавливаем отступы к нулевому элементу.
// Внутри onCreate перед установкой адаптера в RecyclerView
// Здесь мы устанавливаем отступ, равный 20
mRecyclerView.addItemDecoration(new ItemOffsetDecoration(20));
RecyclerView Adapter
Теперь давайте настроим адаптер ReeyclerView с заголовком и футером.
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOTER = 2;
ArrayList<String> mList = new ArrayList<>();
public MyAdapter(ArrayList<String> mList) {
this.mList = mList;
}
@Override
public int getItemViewType(int position) {
if (isPositionHeader(position)) {
return TYPE_HEADER;
} else if (isPositionFooter(position)) {
return TYPE_FOOTER;
}
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
private boolean isPositionFooter(int position) {
return position > mList.size();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == TYPE_ITEM) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_layout, viewGroup, false);
return new ItemViewHolder(view);
} else if (viewType == TYPE_HEADER) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.header_layout, viewGroup, false);
return new HeaderViewHolder(view);
} else if (viewType == TYPE_FOOTER) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.footer_layout,
viewGroup, false);
return new FooterViewHolder(view);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof HeaderViewHolder) {
//Установите значение из списка в соответствующий компонент пользовательского интерфейса, как показано ниже.
((HeaderViewHolder) holder).txtName.setText(mList.get(position))
//Аналогично можно связывать другие компоненты пользовательского интерфейса
}else if (holder instanceof ItemViewHolder) {
// Ваш код здесь
}else if (holder instanceof FooterViewHolder) {
// Ваш код здесь
}
}
@Override
public int getItemCount() {
// Увеличьте на два для размещения заголовка и подвала
return this.mList.size() + 2;
}
// ViewHolders для заголовка, элемента и подвала
class HeaderViewHolder extends RecyclerView.ViewHolder {
public View View;
private final TextView txtName;
public HeaderViewHolder(View itemView) {
super(itemView);
View = itemView;
// Добавьте свои компоненты ui здесь, как показано ниже
txtName = (TextView) View.findViewById(R.id.txt_name);
}
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
public View View;
public ViewHolder(View v) {
super(v);
View = v;
// Добавьте компоненты пользовательского интерфейса здесь.
}
}
public class FooterViewHolder extends RecyclerView.ViewHolder {
public View View;
public ViewHolder(View v) {
super(v);
View = v;
// Добавьте компоненты пользовательского интерфейса здесь.
}
}
}
Пагинация
Теперь, когда адаптер готов, давайте посмотрим, как добавить пагинацию в список RecyclerView. Это довольно легко сделать и должно быть добавлено в onCreate после установки Adapter to Recycler-View.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
int lastvisibleitemposition = mLayoutManager.findLastVisibleItemPosition();
if (lastvisibleitemposition == mAdapter.getItemCount() - 1) {
if (!loading && !isLastPage) {
loading = true;
fetchData((++pageCount));
// Увеличиваем на 1 pagecount при каждой прокрутке для получения данных со следующей страницы
// make loading = false после загрузки данных
// Вызовите mAdapter.notifyDataSetChanged (), чтобы обновить адаптер и макет
}
}
}
});
Всякий раз, когда данные изменяются в mList, вызывайте функцию ниже, чтобы обновить адаптер RecyclerView и показать новые данные.
mAdapter.notifyDataSetChanged();
Надеюсь, что этот пост поможет вам получить общее представление о настройке RecyclerView с заголовком, подвалом и пагинацией.
Комментарии (5)
FireWoolf
23.08.2017 11:24setHasFixedSize — Установите значение true, вы не изменяете высоту или ширину у RecyclerView
А точно это относится именно к RecyclerView? Или может к его элементам?velkonost Автор
23.08.2017 11:32Если размер RecyclerView (самого RecyclerView) ...
… не зависит от содержимого адаптера:
mRecyclerView.setHasFixedSize(true);
… зависит от содержимого адаптера:
mRecyclerView.setHasFixedSize(false);
Установка true не означает, что размер RecyclerView фиксирован, это просто означает, что он не изменится из-за изменения содержимого адаптера.
Также, можете ознакомиться с этим методом в RecyclerView.java
demonit
24.08.2017 07:05статья — мусор. Нет ни одного скрина, нет толком описание метода огранизации футера, навигации… нет в конце концов той самой пагинации (действительно, только от одного слова коробит). Постраничная навигация предусматривает некоторые управляющие элементы, позволяющие ее организовать. Где они здесь?
К переводчикам, конечно, претензии не относятся, за исключением — зачем переводить мусор?
PS: да, и, наконец, нет демо-проекта где все это можно пробовать…
Demon_i
Так все таки «с заголовком, футером и пагинацией», «с заголовком, футером, разбиением на страницы и анимацией» или «с заголовком, подвалом и пагинацией»? Почему бы не писать все на одном языке без коверканных англицизмов, тем более, что Вы знаете перевод и используете его по тексту?