自定义Recycerview支持多种类型,下拉刷新,上拉加载更多的适配器

时间:2022-10-03 14:46:00
项目地址https://github.com/helloworld107/ZhNews public classDailyListAdapterextendsRecyclerView.Adapter {
privateContextmContext; privateResponsemResponse; public intload_state=LOAD_PULL_TO;
//专门用来处理尾部刷新状态的标识,跟适配器类型无关 public static final int LOAD_MORE=0; public static final intLOAD_PULL_TO=1; public static final intLOAD_NONE=2; public static final intLOAD_END=3;
//轮播图和请求尾部算一个吧 private static final int TYPE_TOP= -1; private static final intTYPE_FOOTER= -2;
//列表中间的四种类型,其实只有三种类型,空类星可以不写,切记类似数字最好想回递增不要乱写 private static final intTYPE_HEADLINE= -3; private static final intTYPE_NORMAL_PICTURE= -4; private static final intTYPE_NORMAL_TEXT= -5; private static final intTYPE_EMPTY= -6;
publicDailyListAdapter(Context context, Response response) { mContext= context; this.mResponse= response; }
@Override public intgetItemViewType(intposition) {
//弄了半天只判断头和尾啊 if(position == 0) { returnTYPE_TOP; }else if(position == 1) { returnTYPE_HEADLINE; }else if(position + 1== getItemCount()) { returnTYPE_FOOTER; }else{ //普通类型又分三种情况 Daily daily =mResponse.getFeeds().get(position -2); inttype = daily.getType(); if(type == 0|| type ==2) { returnTYPE_NORMAL_PICTURE; }else if(type == 1) { returnTYPE_NORMAL_TEXT; }else{ returnTYPE_EMPTY; } } }
@Override publicRecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,intviewType) { // Logger.e("viewType " + viewType); // Logger.e("count " + getItemCount()); switch(viewType) { caseTYPE_TOP: View inflate1 = View.inflate(mContext, R.layout.item_zhihu_top_stories,null); TopStoriesViewHolder topStoriesViewHolder =newTopStoriesViewHolder(inflate1); returntopStoriesViewHolder; caseTYPE_FOOTER: View inflate2 = View.inflate(mContext, R.layout.activity_view_footer,null); FooterViewHolder footerViewHolder =newFooterViewHolder(inflate2); returnfooterViewHolder; caseTYPE_HEADLINE: View rootView = View.inflate(parent.getContext(), R.layout.item_daily_headline,null); return newHeadlineViewHolder(rootView); caseTYPE_NORMAL_PICTURE: View rootView1 = View.inflate(parent.getContext(), R.layout.item_daily_feed_0,null); return newFeed_0_ViewHolder(rootView1); caseTYPE_NORMAL_TEXT: View rootView2 = View.inflate(parent.getContext(), R.layout.item_daily_feed_1,null); return newFeed_1_ViewHolder(rootView2); caseTYPE_EMPTY://不实现 View rootView3 = View.inflate(parent.getContext(), R.layout.item_empty,null); return newEmptyViewHolder(rootView3); } View rootView3 = View.inflate(parent.getContext(), R.layout.item_empty,null); return newEmptyViewHolder(rootView3); }
@Override public voidonBindViewHolder(RecyclerView.ViewHolder holder,intposition) {
// getItemViewType(position) //可以通过这种方法判断类型,不过还有中更加简单的方式 if(holderinstanceofDailyListAdapter.FooterViewHolder) { DailyListAdapter.FooterViewHolder footerViewHolder = (DailyListAdapter.FooterViewHolder) holder; //封装方法写在了holder里,6666 footerViewHolder.bindItem(); }else if(holderinstanceofDailyListAdapter.TopStoriesViewHolder) { DailyListAdapter.TopStoriesViewHolder topStoriesViewHolder = (DailyListAdapter.TopStoriesViewHolder) holder; topStoriesViewHolder.bindItem(mResponse.getBanners()); }else if(holderinstanceofFeed_1_ViewHolder) { Daily daily =mResponse.getFeeds().get(position -2); //由于数据的原因,必须判断类型,如果没有类型就不设数据,好坑爹啊,服务器又干什么坏事了 Feed_1_ViewHolder feed1viewholder = (Feed_1_ViewHolder) holder; feed1viewholder.bindItem(daily); }else if(holderinstanceofFeed_0_ViewHolder) { Daily daily =mResponse.getFeeds().get(position -2); Feed_0_ViewHolder feed0viewholder = (Feed_0_ViewHolder) holder; feed0viewholder.bindItem(daily); }else if(holderinstanceofHeadlineViewHolder) { HeadlineViewHolder headlineViewHolder = (HeadlineViewHolder) holder; headlineViewHolder.bindItem(mResponse.getHeadline()); }else{
} }
@Override public intgetItemCount() { returnmResponse.getListSize() +1;//请求头和headline已经帮你加好了,所以再一个请求尾部就可以了,这个比较灵活,要根据实际情况考虑 }
//写这两个方法就是为了开启轮播图功能而已,轮不图是个自定义控件,用起来还不错 @Override public voidonView AttachedToWindow(RecyclerView.ViewHolder holder) { if(holderinstanceofZhihuListAdapter.TopStoriesViewHolder) { ZhihuListAdapter.TopStoriesViewHolder topStoriesViewHolder = (ZhihuListAdapter.TopStoriesViewHolder) holder; topStoriesViewHolder.mVpTopStories.startAutoRun(); } }
@Override public voidonViewDetachedFromWindow(RecyclerView.ViewHolder holder) { if(holderinstanceofZhihuListAdapter.TopStoriesViewHolder) { ZhihuListAdapter.TopStoriesViewHolder topStoriesViewHolder = (ZhihuListAdapter.TopStoriesViewHolder) holder; topStoriesViewHolder.mVpTopStories.stopAutoRun(); } }

classTopStoriesViewHolderextendsRecyclerView.ViewHolder { @Bind(R.id.vp_top_stories) TopStoriesViewPagermVpTopStories; @Bind(R.id.tv_top_title) TextViewmTvTopTitle;
TopStoriesViewHolder(View view) { super(view); ButterKnife.bind(this, view); }
public voidbindItem(List<Daily> banners) { //因为轮播图的类型写死了,所以需要转换一下,好坑爹,应该定义成泛型 List<TopStories> topList =newArrayList<>(); for(Daily d : banners) { TopStories t =newTopStories(); t.setImage(d.getImage()); t.setTitle(d.getPost().getTitle()); t.setUrl(d.getPost().getAppview()); topList.add(t); } mVpTopStories.init(topList,mTvTopTitle,newTopStoriesViewPager.ViewPagerClickListenner() { @Override public voidonClick(TopStories item) { mContext.startActivity(GankWebActivity.newIntent(mContext,item.getUrl())); } });
} }
classFooterViewHolderextendsRecyclerView.ViewHolder {
@Bind(R.id.progress) ProgressBarmProgress; @Bind(R.id.tv_load_prompt) TextViewmTvLoadPrompt;
FooterViewHolder(View view) { super(view); ButterKnife.bind(this, view); //宽度好定,高度麻烦,根据屏幕适配方法用代码写一下,这个方法值得赞一下 ScreenUtil instance = ScreenUtil.instance(mContext); intheight = instance.dip2px(40); LinearLayout.LayoutParams layoutParams =newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); view.setLayoutParams(layoutParams);
}
public voidbindItem() { //请求尾部都在这里处理了,其实也不难 switch(load_state) { caseLOAD_MORE: mTvLoadPrompt.setText("正在加载中。。。"); mProgress.setVisibility(View.VISIBLE); break; caseLOAD_PULL_TO: mTvLoadPrompt.setText("上拉加载更多"); mProgress.setVisibility(View.VISIBLE); break; caseLOAD_NONE: mTvLoadPrompt.setText("已无更多数据"); mProgress.setVisibility(View.GONE); break; caseLOAD_END: mProgress.setVisibility(View.GONE); break; } } } // 提供给外部更新下拉进度条的装 public voidupdateLoadStatus(intstatus) { this.load_state= status; notifyDataSetChanged(); }
classFeed_1_ViewHolderextendsRecyclerView.ViewHolder {
@Bind(R.id.tv_feed_1_title) TextViewtv_feed_1_title; @Bind(R.id.tv_feed_1_type) TextViewtv_feed_1_type; @Bind(R.id.iv_feed_1_type_icon) ImageViewiv_feed_1_type_icon; @Bind(R.id.iv_feed_1_icon) ImageViewiv_feed_1_icon; @Bind(R.id.card_feed_1) CardViewcard_feed_1;
publicFeed_1_ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView);
ScreenUtil screenUtil = ScreenUtil.instance(mContext); //这种适配方法值得学习 card_feed_1.setLayoutParams(newLinearLayout.LayoutParams(screenUtil.getScreenWidth(), ViewGroup.LayoutParams.WRAP_CONTENT)); }
public voidbindItem(Daily daily) { tv_feed_1_title.setText(daily.getPost().getTitle()); tv_feed_1_type.setText(daily.getPost().getCategory().getTitle()); Glide.with(mContext).load(daily.getPost().getCategory().getImage_lab()).centerCrop().into(iv_feed_1_type_icon); Glide.with(mContext).load(daily.getImage()).centerCrop().into(iv_feed_1_icon);
card_feed_1.setOnClickListener(v -> { mContext.startActivity(GankWebActivity.newIntent(mContext, daily.getPost().getAppview()));
}); }

}

classEmptyViewHolderextendsRecyclerView.ViewHolder {
publicEmptyViewHolder(View rootView) { super(rootView); } }
classFeed_0_ViewHolderextendsRecyclerView.ViewHolder {
@Bind(R.id.iv_feed_0_icon) ImageViewiv_feed_0_icon; @Bind(R.id.tv_feed_0_title) TextViewtv_feed_0_title; @Bind(R.id.tv_feed_0_desc) TextViewtv_feed_0_desc; @Bind(R.id.iv_feed_0_type) ImageViewiv_feed_0_type; @Bind(R.id.tv_Feed_0_type) TextViewtv_Feed_0_type; @Bind(R.id.card_layout) CardViewcard_layout;
publicFeed_0_ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView);
ScreenUtil screenUtil = ScreenUtil.instance(mContext); card_layout.setLayoutParams(newLinearLayout.LayoutParams(screenUtil.getScreenWidth(), ViewGroup.LayoutParams.WRAP_CONTENT)); }
public voidbindItem(Daily daily) { tv_feed_0_title.setText(daily.getPost().getTitle()); tv_feed_0_desc.setText(daily.getPost().getDescription()); tv_Feed_0_type.setText(daily.getPost().getCategory().getTitle()); Glide.with(mContext).load(daily.getImage()).centerCrop().into(iv_feed_0_icon);
if(daily.getType() ==0) { Glide.with(mContext).load(R.drawable.feed_0_icon).centerCrop().into(iv_feed_0_type); card_layout.setOnClickListener(v -> { Intent intent = DailyFeedActivity.newIntent(mContext, daily.getPost().getId(), daily.getPost().getDescription(), daily.getPost().getTitle(), daily.getImage()); mContext.startActivity(intent); }); }else if(daily.getType() ==2) {
Glide.with(mContext).load(R.drawable.feed_1_icon).centerCrop().into(iv_feed_0_type); card_layout.setOnClickListener(v -> { Intent intent = GankWebActivity.newIntent(mContext, daily.getPost().getAppview()); mContext.startActivity(intent); }); }

} }
classHeadlineViewHolderextendsRecyclerView.ViewHolder {
@Bind(R.id.tv_headline_1) TextViewtv_headline_1; @Bind(R.id.tv_headline_2) TextViewtv_headline_2; @Bind(R.id.tv_headline_3) TextViewtv_headline_3; @Bind(R.id.card_headline) CardViewcard_headline;
publicHeadlineViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); }
public voidbindItem(Daily daily) { List<HeadLine> headLines = daily.getList(); tv_headline_1.setText(headLines.get(0).getDescription()); tv_headline_2.setText(headLines.get(1).getDescription()); tv_headline_3.setText(headLines.get(2).getDescription());
card_headline.setOnClickListener(v -> { mContext.startActivity(GankWebActivity.newIntent(mContext, daily.getPost().getAppview()));
}); } }
} 总而言之写法中规中矩吧,其实更好的写法应该把轮播图和请求尾部改成listview那样的可以动态添加头和尾这样就更好的实现了分类,开源控件很多,这里就不多说了,下拉刷新交给了布局swiperefresh的去完成了