管理多视图类型 - RecyclerView

时间:2015-11-24 12:57:59

标签: android android-recyclerview

我正在使用this库在RecyclerView中显示多种类型的视图。

这里我使用EnumMapBindAdapter来显示用户信息列表。

我有4个DataBinder类,每个活页夹都有一个大小为3的列表(大小可能会根据而改变 用户帖子)。我有getEnumFromPosition()的问题,根据我的假设,getEnumFromPosition()方法的执行次数应该等于绑定器的数量(4)。但它没有发生。我总共有4个绑定器,我认为getEnumFromPosition()方法应该只执行4次(0,1,2,3),但是执行正在进行。我的假设可能是错的,如果我错了,那怎么可能 我在getEnumFromPosition()中为不同的位置管理了4个绑定器。如果我将else部分放在getEnumFromPosition()方法中,那么当位置超过时它将返回单个视图。

以下是SampleEnumMapAdapter.java的代码

 public class SampleEnumMapAdapter extends EnumMapBindAdapter<SampleEnumMapAdapter.SampleViewType> {

    enum SampleViewType{
        TEXT,IMAGE_AND_TEXT, AUDIO_AND_TEXT, VIDEO_AND_TEXT
    }

    public SampleEnumMapAdapter(){
        putBinder(SampleViewType.TEXT, new TextBinder(this));
        putBinder(SampleViewType.IMAGE_AND_TEXT, new ImageAndTextBinder(this));
        putBinder(SampleViewType.AUDIO_AND_TEXT, new AudioAndTextBinder(this));
        putBinder(SampleViewType.VIDEO_AND_TEXT, new VideoAndTextBinder(this));
    }

    public void setData(List<TextData> dataSetText ,List<ImageAndTextData> dataSetTextAndImage ,List<AudioAndTextData> dataSetTextAndAudio ,List<VideoAndTextData> dataSetTextAndVideo ) {
        ((TextBinder) getDataBinder(SampleViewType.TEXT)).addAll(dataSetText);
        ((ImageAndTextBinder) getDataBinder(SampleViewType.IMAGE_AND_TEXT)).addAll(dataSetTextAndImage);
        ((AudioAndTextBinder) getDataBinder(SampleViewType.AUDIO_AND_TEXT)).addAll(dataSetTextAndAudio);
        ((VideoAndTextBinder) getDataBinder(SampleViewType.VIDEO_AND_TEXT)).addAll(dataSetTextAndVideo);
    }

    @Override
    public SampleViewType getEnumFromPosition(int position){
        if (position == 0) {
            return SampleViewType.TEXT;
        } else if (position == 1) {
            return SampleViewType.IMAGE_AND_TEXT;
        } else if(position == 2){
            return SampleViewType.AUDIO_AND_TEXT;
        }else if(position == 3){
            return SampleViewType.VIDEO_AND_TEXT;
        }
        return null;
    }

    @Override
    public SampleViewType getEnumFromOrdinal(int ordinal) {
        return SampleViewType.values()[ordinal];
    }
}

2 个答案:

答案 0 :(得分:3)

我之前正在研究类似的问题,但我手动配置了RecyclerView适配器,我没有使用任何库。我在这里给你一个示例代码。这是一个完整的多视图类型适配器

    public class UserPostAdapter extends RecyclerView.Adapter<UserPostAdapter.PostViewHolder> {

    private List<UserPostsListItem> postlist;
    Context conetxt;
    LayoutInflater inflater;
    private ViewClickListener mClickListener;
    private ItemViewClickListener itemViewClickListener;
    int count;

    public UserPostAdapter() {

    }

    public UserPostAdapter(Context conetxt, List<UserPostsListItem> postlist) {
        this.postlist = postlist;
        this.conetxt = conetxt;
        inflater = LayoutInflater.from(this.conetxt);
    }

    @Override
    public int getItemCount() {
        int size = 0;
        if (postlist != null)
            size = postlist.size();
        return size;
    }

    @Override
    public int getItemViewType(int position) {
        int viewTypePosition =0;

        String attachment_type = postlist.get(position).getAttachment_type();

        switch (attachment_type){

            case "text":
                viewTypePosition = 0 ;
                break;
            case "image":
                viewTypePosition = 1 ;
                break;
            case "audio":
                viewTypePosition = 2 ;
                break;
            case "video":
                viewTypePosition = 3 ;
                break;
            default:
        }

        return viewTypePosition;
    }

    @Override
    public void onBindViewHolder(final PostViewHolder videoViewHolder, final int position) {

        //Log.d("onBindViewHolder",Integer.toString(position));
        final UserPostsListItem item = postlist.get(position);

        switch (item.getAttachment_type()){
            case "audio":

                break;
            case "video":

                break;
            case "text":

                break;
            case "image":

                break;           
            default:
        }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public interface ItemViewClickListener {
        void onItemChildClicked(int position ,String type);
    }

    public void setItemViewClickListener (ItemViewClickListener viewClickListener) {
        itemViewClickListener = viewClickListener;
    }


    public List<UserPostsListItem> getUserPostsList() {
        return postlist;
    }

    @Override
    public PostViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){

        Log.d("ViewType", Integer.toString(viewType));
        switch (viewType) {
            case 0:
                View itemViewText = inflater.inflate(R.layout.userposts_listitem_text, viewGroup, false);
                return new PostViewHolder(itemViewText ,viewType);

            case 1:
                View itemViewTextImage = inflater.inflate(R.layout.userposts_listitem_textandimage, viewGroup, false);
                return new PostViewHolder(itemViewTextImage,viewType);

            case 2:
                View itemViewTextAudio = inflater.inflate(R.layout.userposts_listitem_audioandtext, viewGroup, false);
                return new PostViewHolder(itemViewTextAudio,viewType);

            case 3:
                View itemViewTextVideo = inflater.inflate(R.layout.userposts_listitem_videoandtext, viewGroup, false);
                return new PostViewHolder(itemViewTextVideo,viewType);

            default:
        }

        return null;

    }

    public interface ViewClickListener {
        void onVideoClicked(int position,View v);
    }

    public List<UserPostsListItem> getVideoItems() {
        return postlist;
    }

    public void setViewClickListener (ViewClickListener viewClickListener) {
        mClickListener = viewClickListener;
    }

    public static class PostViewHolder extends RecyclerView.ViewHolder {
        ImageView attachment;
        CircleImageView circleImageView;
        ImageView audio;
        public PostViewHolder(View v,int viewtype) {
            super(v);
            switch (viewtype){
                //For Audio
                case 2:                    
                    break;                  
                //For Video
                case 3:                    
                    break;
                //For Text only
                case 0:
                    break;
                //For Image
                case 1:                    
                    break;                
                default:

            }
        }
    }

}

答案 1 :(得分:0)

不要按位置管理活页夹,按照要在该位置存储/显示的数据类型管理活页夹。向SampleViewType添加一个类型字段,并在每个位置上将该类型与其相应的活页夹匹配,并加载其各自的数据。

解释示例:

您主要需要更改适配器中的一个方法。为了便于解释,我们假设您正在为适配器中的数据列表进行膨胀。让列表的名称数据。 你的方法getEnumFromPosition()看起来像这样: -

@Override
public SampleViewType getEnumFromPosition(int position){
    return data.get(position).getViewType();
}

在上面的代码行中,data是你的列表,get方法从列表中获取一个对象。此对象的类型为SampleViewType。在类SampleViewType中,您需要创建一个名为type的数据成员,该成员将保存类SampleViewType的每个对象的类型,并将具有名为getViewType()的getter函数。此getViewType()函数将返回该特定SampleViewType对象的类型,如SampleViewType.TEXT等,就像您返回的位置一样。

您可能需要创建一个名为SampleView的单独类,并使用它为您的适配器充气,而您的SampleViewType类将保存所有类型的SampleView的重要信息。

我希望这个例子能够解释你想传达的内容,如果有任何混淆,请随时提出。