根据RecyclerView每行中的数据类型,增加行的视图

时间:2016-07-30 15:48:37

标签: android android-recyclerview

我目前正在开发一个有Recyclerview的android项目。 Recyclerview持有不同类型的物品。项目是不同的文件(Doc,Pdf,图像和视频)。我正在使用Gridlayoutmanager。我想在recyclerview中将两种类型的视图扩展为行,一个视图用于图像和视频,另一个视图用于其他类型的文件(doc,pdf等)。所有文件都是混合,不知道哪种类型的文件在哪个顺序。我知道我必须使用getItemViewTypeonCreateViewHolder来扩充行。如果我使用通用方式首先膨胀行并根据膨胀行的类型填充行不起作用,因为所有文件都是随机的。我想根据文件类型对行进行充气。可能是我需要从getItemViewType触发onBindViewHolder,以便扩充所需的类型。我在SO中读过问题。毫无疑问与此问题直接相关。所有问题都是首先膨胀行并填充行中的详细信息。任何想法如何根据细节的类型(我的情况下的文件)膨胀?

2 个答案:

答案 0 :(得分:1)

在你的适配器类中创建:

 class ViewHolder{

     public ViewHolder(View v, int type){

         super(itemView);
         this.type=type; //here we have type of view holder
     }
 }

在Adapter实现方法中:

final int VIEW_VIDEO=2;
final int VIEW_STANDARD=1; 
public int getItemViewType(int position) {

    //here return some view type
    if (isVideo(position)){ //example method checking is video row

       return VIEW_VIDEO;
    }else{

       return VIEW_STANDARD
    }
}
  

如果我使用通用方式首先给行充气并根据行的类型填充行不起作用,因为所有文件都是随机的

getItemViewType 您有位置,所以这可能是可以检查此行中的哪种文件。如果您的适配器有数据(如果列表显示肯定有),那么可以检查我们需要在视图上设置哪种文件。

示例isVideo方法检查文件扩展名:

 private boolean isVideo(position){

    String filename=list.get(position); //list Your Strings
    String filenameArray[] = filename.split("\\.");
    String extension = filenameArray[filenameArray.length-1];
    return extension=="mp4"; //change this to more flexible
 }

在Adapter中实现的下一个方法:

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){

   View v;

   if (viewType==VIEW_VIDEO){

      v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.video_layout, parent, false);
   }else{

       v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.standard_layout, parent, false);
   }

   return new ViewHolder(v,viewType); //here we have view holder with right view

}

适配器中的最后一件事:

public void onBindViewHolder(final ViewHolder holder, int position){

    if (holder.type==VIEW_VIDEO){

       //staff on video
    }
}

答案 1 :(得分:0)

有很多解决方案,但这个是我的最爱:

public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.FeedItemHolder> {

    static final int VIEW_TYPE_HEADER = 0;
    static final int VIEW_TYPE_NORMAL = 1;
    static final int VIEW_TYPE_FOOTER = 2;

    @Override
    public FeedItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        logd("create view holder called");

        int resid = 0;

        if (viewType == VIEW_TYPE_HEADER) {
            resid = R.layout.item_header;
        } else if (viewType == VIEW_TYPE_NORMAL) {
            resid = R.layout.item_normal;
        } else if (viewType == VIEW_TYPE_FOOTER) {
            resid = R.layout.item_footer;
        }

        View v = LayoutInflater.from(context).inflate(resid, parent, false);
        return new FeedItemHolder(context, viewType);
    }

    private void bindNormal(FeedItemHolder holder, int position) {
        // specialized bind method for normal items
        ...
    }

    private void bindHeader(FeedItemHolder holder, int position) {
        // specialized bind method for header items
        ...
    }

    private void bindFooter(FeedItemHolder holder, int position) {
        // specialized bind method for footer items
        ...
    }

    @Override
    public void onBindViewHolder(FeedItemHolder holder, int position) {

        int viewType = getItemViewType(position);

        if (viewType == VIEW_TYPE_HEADER) {
            bindHeader(holder, position);
        } else if (viewType == VIEW_TYPE_NORMAL) {
            bindNormal(holder, position);
        } else if (viewType == VIEW_TYPE_FOOTER) {
            bindFooter(holder, position);
        }

    }

    @Override
    public int getItemViewType(int position) {

        // determine view type, e.g:
        //
        // if (position == 0)
        //      return VIEW_TYPE_HEADER;
        // else if (postion > itemCount)
        //      return VIEW_TYPE_FOOTER;
        // else
        //      return VIEW_TYPE_NORMAL;

        ...
    }

    private View.OnClickListener showCommentsListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (holder != null) {
                TimelineEntryRaw entry = (TimelineEntryRaw) v.getTag();
                holder.onCommentsRequest(entry, false);
            }
        }
    };

    public class FeedItemHolder extends RecyclerView.ViewHolder {

        private View root;

        // header items' views
        private TextView title;
        ...

        // normal items' views 
        private TextView contentText;
        ...

        // footer items' views
        private View loadMoreBtn;
        ...

        public FeedItemHolder(View itemView, int itemType) {

            // the call to parent constructor is the only
            // reason android knows which view to show
            super(itemView);

            root = itemView;

            if (itemType == VIEW_TYPE_HEADER) {

                // fetch header item views
                loadMoreBtn = findView(itemView, R.id.item_header__title);
                ...

            }

            if (itemType == VIEW_TYPE_NORMAL) {

                // fetch views for normal item
                contentText = findView(itemView, R.id.item_normal__content);
                ...

            }

            if (itemType != VIEW_TYPE_FOOTER) {

                // fetch views for footer item
                loadMoreBtn = findView(itemView, R.id.item_footer__btn);
                ...

            }

        } // end Holder constructor


    } // end class Holder

}

长话短说,在create-view-holder和bind-view-holder中,你必须根据视图类型创建和绑定视图