image


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, чтобы удовлетворить наши требования.

Виды Layout Manager
  1. LinearLayoutManager показывает элементы в списке с вертикальной или горизонтальной прокруткой.
  2. GridLayoutManager показывает элементы в сетке.
  3. 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 с заголовком, подвалом и пагинацией.