Pull to refresh

Реализация списка с заголовком, футером и пагинацией в Андроид

Reading time 5 min
Views 17K
Original author: ANU S PILLAI

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 с заголовком, подвалом и пагинацией.

Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
+2
Comments 5
Comments Comments 5

Articles