Установить липкий заголовок и макеты элементов Recyclerview

Я хочу построить сложный макет с использованием реселлера просмотра Android. В макете я хочу, чтобы кнопка камеры в верхнем левом углу была зафиксирована, а представление оберточного экрана было обернуто вокруг нее изображениями галереи. я проверил flexbox layout manager for recyclerview но это не похоже на мой вариант использования.

Я хочу, чтобы заголовок не повторялся и не прокручивался с другими элементами по вертикали. Вот макет для заголовка:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/shareLayout"
android:layout_width="185dp"
android:layout_height="135dp"
android:layout_below="@id/trendingToolbar"
android:background="@color/black">

<ImageView
    android:id="@+id/cameraShareIV"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="10dp"
    app:srcCompat="@drawable/camera_white" />

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/cameraShareIV"
    android:layout_centerHorizontal="true">

    <TextView
        android:id="@+id/infoTxt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="20dp"
        android:gravity="center_horizontal"
        android:text="@string/share_pic_video"
        android:textColor="@android:color/white"
        android:textSize="13sp"
        android:textStyle="bold" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/infoTxt"
        android:layout_marginLeft="16dp"
        android:text="@string/share_timeout_txt"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="11sp"
        android:textStyle="bold" />

</RelativeLayout>

и в моей деятельности вот XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="base.android.com.thumbsapp.UI.Fragments.TrendingFragment">

<include layout="@layout/trending_toolbar"
    android:id="@+id/trendingToolbar"/>

<android.support.v7.widget.RecyclerView
    android:id="@+id/trendingRV"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/trendingToolbar"/>

Раньше у меня был заголовок внутри XML-файла активности, но у меня не было возможности обернуть вокруг него представление переработчика. Итак, я решил использовать адаптер, как показано ниже:

public class TrendingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private static final String TAG = TrendingAdapter.class.getSimpleName();

private Context context;
private List<Trending> itemList;

private static final int HEADER = 0;
private static final int ITEMS = 1;

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;
    switch (viewType){
        case HEADER:
           v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_header, parent, false);
           return new TrendingHeaderViewHolder(v);
        case ITEMS:
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_items_layout, parent, false);
            return new TrendingItemsViewHolder(v);
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    Trending tr = itemList.get(position);
    if (holder instanceof TrendingHeaderViewHolder){
        ((TrendingHeaderViewHolder) holder).cameraShareIV.setOnClickListener( view -> {
            // TODO: 4/2/2018   select image from gallery
        });
    } else if (holder instanceof TrendingItemsViewHolder){
        // TODO: 4/2/2018 populate gallery items here with picasso  
    }
}

@Override
public int getItemCount() {
    return itemList.size();
}

@Override
public int getItemViewType(int position) {
    return super.getItemViewType(position);
}
}

Я запутался, как сделать заголовок, а также что делать для getItemViewType method,

Это правильный способ подойти к этому? Кто-нибудь может помочь? Благодарю.

2 ответа

Для этой раскладки я предлагаю лучший вариант - использовать это представление заголовка https://github.com/edubarr/header-decor

Для простоты предлагаю заглянуть в эту библиотеку

В вашем XML Поместите RecylerView в StickyHeaderViewвыберите горизонтальную или вертикальную ориентацию для вашего RecylerView

 <tellh.com.stickyheaderview_rv.StickyHeaderView
        android:id="@+id/stickyHeaderView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:scrollbars="vertical" />
    </tellh.com.stickyheaderview_rv.StickyHeaderView>

Создайте класс компонента данных для каждого типа элемента в RecyclerView. Они должны расширяться DataBean, Переопределить метод public boolean shouldSticky() решить, должен ли вид элемента быть приостановлен сверху.

public class User extends DataBean {
    private String login;
    private int id;
    private String avatar_url;
    private boolean shouldSticky;
    @Override
    public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
        return R.layout.item_user;
    }
    public void setShouldSticky(boolean shouldSticky) {
        this.shouldSticky = shouldSticky;
    }
    // Decide whether the item view should be suspended on the top.
    @Override
    public boolean shouldSticky() {
        return shouldSticky;
    }
}
public class ItemHeader extends DataBean {
    private String prefix;
    @Override
    public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
        return R.layout.header;
    }
    @Override
    public boolean shouldSticky() {
        return true;
    }
}

Создайте ViewBinder связывать различные типы представлений с конкретными компонентами данных. Как вы видите, provideViewHolder(View itemView) соответствует для onCreateViewHolder в RecyclerView, а также bindView соответствует для onBindViewHolder в RecyclerView,

public class ItemHeaderViewBinder extends ViewBinder<ItemHeader, ItemHeaderViewBinder.ViewHolder> {
    @Override
    public ViewHolder provideViewHolder(View itemView) {
        return new ViewHolder(itemView);
    }
    @Override
    public void bindView(StickyHeaderViewAdapter adapter, ViewHolder holder, int position, ItemHeader entity) {
        holder.tvPrefix.setText(entity.getPrefix());
    }
    @Override
    public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
        return R.layout.header;
    }
    static class ViewHolder extends ViewBinder.ViewHolder {
        TextView tvPrefix;
        public ViewHolder(View rootView) {
            super(rootView);
            this.tvPrefix = (TextView) rootView.findViewById(R.id.tv_prefix);
        }
    }
}

иллюстрировать примерами StickyHeaderViewAdapter за RecyclerView и зарегистрируйтесь ViewBinders для каждого типа предметов.

rv = (RecyclerView) findViewById(R.id.recyclerView);
    rv.setLayoutManager(new LinearLayoutManager(this));
    List<DataBean> userList = new ArrayList<>();
    adapter = new StickyHeaderViewAdapter(userList)
            .RegisterItemType(new UserItemViewBinder())
            .RegisterItemType(new ItemHeaderViewBinder());
    rv.setAdapter(adapter);
Другие вопросы по тегам