我正在寻找一个相当于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();
    }
}

Fragment的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;
}

包含recycleview的片段:

<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>

适配器代码(感谢hister让我开始):

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 = 1;

    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。它是这样的。如果我强制另一个布局,它看起来像这样:


当前回答

请随意使用我的图书馆,这里有。

它可以让你创建任何RecyclerView的头视图,使用LinearLayoutManager或GridLayoutManager只需一个简单的方法调用。

其他回答

基于这篇文章,我创建了一个RecyclerView的子类。支持任意数量的页眉和页脚的适配器。

https://gist.github.com/mheras/0908873267def75dc746

虽然这似乎是一个解决方案,但我也认为这个东西应该由LayoutManager管理。不幸的是,我现在需要它,我没有时间从头开始实现StaggeredGridLayoutManager(甚至也没有从它扩展)。

我还在测试,但如果你想试试也可以。如果你发现有任何问题,请告诉我。

没有像listview.addHeaderView()这样简单的方法,但您可以通过向您的头适配器添加类型来实现这一点。

这里有一个例子

public class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;
    String[] data;

    public HeaderAdapter(String[] data) {
        this.data = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_ITEM) {
            //inflate your layout and pass it to view holder
            return new VHItem(null);
        } else if (viewType == TYPE_HEADER) {
            //inflate your layout and pass it to view holder
            return new VHHeader(null);
        }

        throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof VHItem) {
            String dataItem = getItem(position);
            //cast holder to VHItem and set data
        } else if (holder instanceof VHHeader) {
            //cast holder to VHHeader and set data for header.
        }
    }

    @Override
    public int getItemCount() {
        return data.length + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position))
            return TYPE_HEADER;

        return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }

    private String getItem(int position) {
        return data[position - 1];
    }

    class VHItem extends RecyclerView.ViewHolder {
        TextView title;

        public VHItem(View itemView) {
            super(itemView);
        }
    }

    class VHHeader extends RecyclerView.ViewHolder {
        Button button;

        public VHHeader(View itemView) {
            super(itemView);
        }
    }
}

链接到gist ->

原生API没有这样的“addHeader”特性,但有“addItem”的概念。

我能够在我的FlexibleAdapter项目中包括页眉和页脚扩展的特定功能。我称之为可滚动的页眉和页脚。

以下是它们的工作原理:

可滚动的页眉和页脚是与其他所有项一起滚动的特殊项,但它们不属于主项(业务项),它们总是由适配器在主项旁边处理。这些项持久地位于第一个和最后一个位置。

关于它们有很多可说的,最好阅读详细的维基页面。

此外,FlexibleAdapter允许你创建标题/部分,也可以让他们粘和其他几十个功能,如可扩展的项目,无尽的滚动,UI扩展等…都在一个图书馆里!

First - extends RecyclerView.Adapter<RecyclerView.ViewHolder>

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

重载getItemViewTpe方法后 * * *更重要

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

方法onCreateViewHolder

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_item, parent, false);
    View header = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_header_item, parent, false);
    Log.d("onCreateViewHolder", String.valueOf(viewType));

    if (viewType == 0) {
        return new MenuLeftHeaderViewHolder(header, onClickListener);
    } else {
        return new MenuLeftViewHolder(view, onClickListener);
    }
}

方法onBindViewHolder

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (position == 0) {
        MenuHeaderViewHolder menuHeaderViewHolder = (MenuHeaderViewHolder) holder;
        menuHeaderViewHolder.mTitle.setText(sMenuTitles[position]);
        menuHeaderViewHolder.mImage.setImageResource(sMenuImages[position]);
    } else {
        MenuViewHolder menuLeftViewHolder = (MenuLeftViewHolder) holder;
        menuViewHolder.mTitle.setText(sMenuTitles[position]);
        menuViewHolder.mImage.setImageResource(sMenuImages[position]);
    }
}

在finish中实现了ViewHolders类静态

public static class MenuViewHolder extends RecyclerView.ViewHolder 

public static class MenuLeftHeaderViewHolder extends RecyclerView.ViewHolder 

也许http://alexzh.com/tutorials/multiple-row-layouts-using-recyclerview/会有帮助。它只使用RecyclerView和CardView。 这是一个适配器:

public class DifferentRowAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<CityEvent> mList;
    public DifferentRowAdapter(List<CityEvent> list) {
        this.mList = list;
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case CITY_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_city, parent, false);
                return new CityViewHolder(view);
            case EVENT_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
                return new EventViewHolder(view);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        CityEvent object = mList.get(position);
        if (object != null) {
            switch (object.getType()) {
                case CITY_TYPE:
                    ((CityViewHolder) holder).mTitle.setText(object.getName());
                    break;
                case EVENT_TYPE:
                    ((EventViewHolder) holder).mTitle.setText(object.getName());
                    ((EventViewHolder) holder).mDescription.setText(object.getDescription());
                    break;
            }
        }
    }
    @Override
    public int getItemCount() {
        if (mList == null)
            return 0;
        return mList.size();
    }
    @Override
    public int getItemViewType(int position) {
        if (mList != null) {
            CityEvent object = mList.get(position);
            if (object != null) {
                return object.getType();
            }
        }
        return 0;
    }
    public static class CityViewHolder extends RecyclerView.ViewHolder {
        private TextView mTitle;
        public CityViewHolder(View itemView) {
            super(itemView);
            mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
        }
    }
    public static class EventViewHolder extends RecyclerView.ViewHolder {
        private TextView mTitle;
        private TextView mDescription;
        public EventViewHolder(View itemView) {
            super(itemView);
            mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
            mDescription = (TextView) itemView.findViewById(R.id.descriptionTextView);
        }
    }
}

这是一个实体:

public class CityEvent {
    public static final int CITY_TYPE = 0;
    public static final int EVENT_TYPE = 1;
    private String mName;
    private String mDescription;
    private int mType;
    public CityEvent(String name, String description, int type) {
        this.mName = name;
        this.mDescription = description;
        this.mType = type;
    }
    public String getName() {
        return mName;
    }
    public void setName(String name) {
        this.mName = name;
    }
    public String getDescription() {
        return mDescription;
    }
    public void setDescription(String description) {
        this.mDescription = description;
    }
    public int getType() {
        return mType;
    }
    public void setType(int type) {
        this.mType = type;
    }
}