Я ищу эквивалент addHeaderView для представления переработчика. В основном я хочу, чтобы изображение с 2 кнопками было добавлено в качестве заголовка к списку. Есть ли другой способ добавить представление заголовка в представление переработчика? Пример для руководства будет полезным
РЕДАКТИРОВАТЬ 2 (добавлены фрагменты макетов):
После добавления операторов журнала кажется, что getViewType всегда получает только позицию 0. Это приводит к тому, что onCreateView загружает только один макет:
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> onCreateViewHolder, viewtype: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> onBindViewHolder, viewType: 0
Фрагмент перехода для загрузки CommentFragment:
@Override
public void onPhotoFeedItemClick(View view, int position) {
if (fragmentManager == null)
fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (view.getId() == R.id.button_comment){
CommentFragment commentFragment = CommentFragment.newInstance("","", position);
fragmentTransaction.add(R.id.main_activity, commentFragment,"comment_fragment_tag");
fragmentTransaction.addToBackStack(Constants.TAG_COMMENTS);
fragmentTransaction.commit();
}
}
OnCreateView фрагмента:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_comment, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.list_recylclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(_context));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter = new CommentAdapter(R.layout.row_list_comments, R.layout.row_header_comments, _context, comments);
mRecyclerView.setAdapter(mAdapter);
return view;
}
Фрагмент, содержащий повторное представление:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="co.testapp.fragments.CommentFragment"
android:background="@color/white">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_recylclerview"
android:layout_width="match_parent"
android:layout_height="200dp" />
</RelativeLayout>
</RelativeLayout>
Расположение строк комментариев:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_margin="10dp"
android:background="@color/white">
<!--Profile Picture-->
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/profile_picture"
android:background="@color/blue_testapp"/>
<!--Name-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="First Name Last Name"
android:textSize="16dp"
android:textColor="@color/blue_testapp"
android:id="@+id/name_of_poster"
android:layout_toRightOf="@id/profile_picture"
/>
<!--Comment-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="-5dp"
android:text="This is a test comment"
android:textSize="14dp"
android:textColor="@color/black"
android:id="@+id/comment"
android:layout_below="@id/name_of_poster"
android:layout_toRightOf="@id/profile_picture"/>
</RelativeLayout>
Заголовок
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="300dp"
android:id="@+id/header_photo"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
Код адаптера (спасибо Гистеру за то, что я начал):
public class CommentAdapter extends RecyclerView.Adapter<ViewHolder>{
private final int rowCardLayout;
public static Context mContext;
private final int headerLayout;
private final String [] comments;
private static final int HEADER = 0;
private static final int OTHER = 0;
public CommentAdapter(int rowCardLayout, int headerLayout, Context context, String [] comments) {
this.rowCardLayout = rowCardLayout;
this.mContext = context;
this.comments = comments;
this.headerLayout = headerLayout;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
logger.i("onCreateViewHolder, viewtype: " + i); //viewtype always returns 0 so OTHER layout is never inflated
if (i == HEADER) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(headerLayout, viewGroup, false);
return new ViewHolderHeader(v);
}
else if (i == OTHER){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowCardLayout, viewGroup, false);
return new ViewHolderComments(v);
}
else
throw new RuntimeException("Could not inflate layout");
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
logger.i("onBindViewHolder, viewType: " + i);
if (viewHolder instanceof ViewHolderComments)
((ViewHolderComments) viewHolder).comment.setText(comments[i].toString());
if (viewHolder instanceof ViewHolderHeader)
((ViewHolderHeader) viewHolder).header.setImageResource(R.drawable.image2);
else {
logger.e("no instance of viewholder found");
}
}
@Override
public int getItemCount() {
int count = comments.length + 1;
logger.i("getItemCount: " + count);
return count;
}
@Override
public int getItemViewType(int position) {
logger.i("getItemViewType position: " + position);
if (position == HEADER)
return HEADER;
else
return OTHER;
}
public static class ViewHolderComments extends RecyclerView.ViewHolder {
public TextView comment;
public ImageView image;
public ViewHolderComments(View itemView) {
super(itemView);
comment = (TextView) itemView.findViewById(R.id.comment);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
public static class ViewHolderHeader extends RecyclerView.ViewHolder {
public final ImageView header;
public ViewHolderHeader(View itemView){
super(itemView);
header = (ImageView) itemView.findViewById(R.id.header_photo);
}
}
}
Используя приведенный выше код, только расположение заголовка отображается как viewType всегда 0. Похоже , это . Если я заставляю другой макет выглядит как это :
источник
Ответы:
Легкого пути не существует,
listview.addHeaderView()
но вы можете достичь этого, добавив в заголовок тип адаптера.Вот пример
ссылка на суть -> здесь
источник
private String getItem(int position) { return data[position + 1]; }
Вызывает NPE. Поскольку наша позиция была увеличена на единицу из-за заголовка, мы должны вычесть 1, чтобы получить правильный элемент из наших данных [].private String getItem(int position) { return data[position - 1]; }
setSpanSizeLookup
кGridLayoutManager
, так что ваш заголовок будет принимать все столбцыЛегко и многоразово
ItemDecoration
Статические заголовки могут быть легко добавлены с
ItemDecoration
и без каких-либо дальнейших изменений.Украшение также можно использовать повторно, так как нет необходимости изменять адаптер или
RecyclerView
вообще.Пример кода, представленный ниже, потребует добавления вида сверху, который можно просто надуть, как и все остальное. Это может выглядеть так:
Почему статический ?
Если вам просто нужно отобразить текст и изображения, то это решение для вас - нет возможности для взаимодействия с пользователем, например, для кнопок или просмотра пейджеров, поскольку оно будет просто отображено в верхней части вашего списка.
Обработка пустого списка
Если нет вида для украшения, украшение не будет нарисовано. Вам все равно придется обрабатывать пустой список самостоятельно. (Одним из возможных путей решения этой проблемы является добавление фиктивного элемента в адаптер.)
Код
Вы можете найти полный исходный код здесь на GitHub, включая
Builder
чтобы помочь с инициализацией декоратора, или просто используйте приведенный ниже код и предоставьте свои собственные значения конструктору.Пожалуйста, не забудьте установить правильный
layout_height
для вашего взгляда. например,match_parent
может не работать должным образом.Обратите внимание: проект GitHub - это моя личная игровая площадка. Он не был тщательно протестирован, поэтому библиотеки пока нет .
Что оно делает?
Дополнительный
ItemDecoration
рисунок к элементу списка. В этом случае украшение рисуется в верхней части первого элемента.Представление измеряется и раскладывается, затем оно обращается к вершине первого элемента. Если добавлен эффект параллакса, он также будет обрезан до правильных границ.
источник
Не стесняйтесь использовать мою библиотеку, доступную здесь .
Это позволит вам создать заголовок
View
для любого,RecyclerView
который используетLinearLayoutManager
илиGridLayoutManager
просто с помощью простого вызова метода.источник
Будет показано, как сделать заголовок с элементами в представлении Recycler.
Шаг 1 - Добавьте зависимость в ваш файл Gradle.
Cardview используется для украшения.
Шаг 2. Сделайте три XML-файла. Один для основного действия. Второй для расположения заголовка. Третий для расположения элемента списка.
activity_main.xml
header.xml
list.xml
Шаг 3 - Создайте три бобовых класса.
Header.java
ContentItem.java
ListItem.java
Шаг 4 - Создайте адаптер с именем MyRecyclerAdapter.java
Шаг 5 - В MainActivity добавьте следующий код:
Функция getList () динамически генерирует данные для заголовков и элементов списка.
источник
Добиться этого можно с помощью библиотеки SectionedRecyclerViewAdapter , в ней есть понятие «Разделы», где у какого Раздела есть Верхний колонтитул, Нижний колонтитул и Содержимое (список элементов). В вашем случае вам может понадобиться только один раздел, но вы можете иметь много:
1) Создайте собственный класс раздела:
2) Создайте пользовательский ViewHolder для элементов:
3) Настройте ваш ReclyclerView с помощью SectionedRecyclerViewAdapter
источник
Вы можете просто поместить свой заголовок и RecyclerView в NestedScrollView:
Для правильной работы прокрутки необходимо отключить вложенную прокрутку в RecyclerView:
источник
Нативный API не имеет такой функции addHeader, но имеет концепцию addItem.
Мне удалось включить эту особенность заголовков и расширений для нижних колонтитулов, а также в мой проект FlexibleAdapter . Я назвал это прокручиваемыми колонтитулами .
Вот как они работают:
Прокручиваемые верхние и нижние колонтитулы - это специальные элементы, которые прокручиваются вместе со всеми остальными, но они не принадлежат основным элементам (бизнес-элементам) и всегда обрабатываются адаптером рядом с основными элементами. Эти предметы постоянно находятся на первой и последней позициях.
О них можно многое рассказать, лучше прочитать подробную вики-страницу .
Более того, FlexibleAdapter позволяет вам создавать заголовки / разделы, также вы можете сделать их липкими и десятки других функций, таких как расширяемые элементы, бесконечная прокрутка, расширения пользовательского интерфейса и т. Д. - все в одной библиотеке!
источник
Основываясь на этом посте , я создал подкласс RecyclerView.Adapter, который поддерживает произвольное количество верхних и нижних колонтитулов.
https://gist.github.com/mheras/0908873267def75dc746
Хотя это кажется решением, я также думаю, что этим должен управлять LayoutManager. К сожалению, мне это нужно сейчас, и у меня нет времени, чтобы реализовать StaggeredGridLayoutManager с нуля (и даже не расширять его).
Я все еще проверяю это, но вы можете попробовать это, если хотите. Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы с ним.
источник
Существует еще одно решение, которое охватывает все приведенные выше варианты использования: CompoundAdapter: https://github.com/negusoft/CompoundAdapter-android
Вы можете создать группу AdapterGroup, которая будет содержать ваш адаптер как есть, а также адаптер с одним элементом для представления заголовка. Код прост и читабелен:
AdapterGroup также допускает вложение, поэтому для адаптера с разделами вы можете создать AdapterGroup для каждого раздела. Затем поместите все разделы в корневую группу AdapterGroup.
источник
HeaderView зависит от LayoutManager. Ни один из LayoutManager по умолчанию не поддерживает это и, вероятно, не будет. HeaderView в ListView создает много сложности без каких-либо существенных преимуществ.
Я бы предложил создать базовый класс адаптера, который добавляет элементы для заголовков, если таковые имеются. Не забудьте переопределить методы notify *, чтобы корректно их компенсировать в зависимости от того, присутствует заголовок или нет.
источник
ListView.addHeaderView
как ответа на этот вопрос.После - переопределить метод getItemViewTpe *** Более важно
метод onCreateViewHolder
метод onBindViewHolder
в финише реализует статический класс ViewHolders
источник
здесь какой-то предмет декорации для переработчика
источник
Я сделал реализацию, основанную на @ hister's, для моих личных целей, но используя наследование.
Я скрываю механизмы детализации реализации (например, добавление 1 к
itemCount
, вычитание 1 изposition
) в абстрактном суперклассеHeadingableRecycleAdapter
, реализуя требуемые методы, подобные адаптеруonBindViewHolder
,getItemViewType
иgetItemCount
делая эти методы окончательными, и предоставляя новые методы со скрытой логикой для клиента:onAddViewHolder(RecyclerView.ViewHolder holder, int position)
,onCreateViewHolder(ViewGroup parent)
,itemCount()
Вот
HeadingableRecycleAdapter
класс и клиент. Я оставил заголовок немного жестко закодированным, потому что он соответствует моим потребностям.источник
Может быть, обернуть заголовок и переработчик в координатор :
источник
Наверное, http://alexzh.com/tutorials/multiple-row-layouts-using-recyclerview/ поможет. Он использует только RecyclerView и CardView. Вот адаптер:
А вот и сущность:
источник
Вы можете создать addHeaderView и использовать
adapter.addHeaderView(View)
,Этот код создает
addHeaderView
более одного заголовка. заголовки должны иметь:android:layout_height="wrap_content"
источник
Прошло несколько лет, но на тот случай, если кто-нибудь прочтет это позже ...
Проблема в постоянном объявлении:
Если вы объявите их обоих как ноль, то вы всегда получите ноль!
источник
Я реализовал тот же подход, предложенный в ответе EC84B4 , но я абстрагировал RecycleViewAdapter и сделал его легко повторяемым с помощью интерфейсов.
Поэтому, чтобы использовать мой подход, вы должны добавить следующие базовые классы и интерфейсы в ваш проект:
1) Интерфейс, который предоставляет данные для Адаптера (набор универсального типа T и дополнительные параметры (при необходимости) универсального типа P)
2) Фабрика для привязки ваших товаров (заголовок / товар):
3) Фабрика для viewHolders (заголовок / элементы):
4) Базовый класс для адаптера с заголовком:
Пример использования :
1) Реализация IRecycleViewListHolder:
2) Реализация IViewHolderBinderFactory:
3) Реализация IViewHolderFactory:
4) Получающий адаптер
5) Создание класса адаптера:
PS : AssetItemViewHolder, AssetBasedListItemBinding и т. Д. Мои приложения имеют собственные структуры, которые должны быть заменены вашими собственными для ваших собственных целей.
источник