接下来整理下以下功能:
1. 通过RecyclerView来展示新闻列表。
2. 根据不同的Item选项来展示不同的布局。
3. 在RecyclerView的基础上实现上拉刷新和下拉加载更多
最终效果图如下:
关于RecyclerView的详细介绍,可以看下鸿洋大神的这篇博客:
Android RecyclerView 使用完全解析 体验艺术般的控件
此处关于第一个 通过RecyclerView来展示新闻列表,不在过多说明,主要说下,2,3功能
此项目中新闻首页的Item有三种布局,如果获取来的新闻数据中有图片新闻,则通过一个轮播控件SliderLayout将所有获取来的图片新闻进行展示,另外一个就是显示普通新闻的Item布局,另外在加载更多时,需要在新闻列表最后展示一个正在加载更多的进度条布局。
在RecyclerView中根据不同的Item选项来展示不同的布局,需要
1.定义对应的int型参数值来代表不同的布局
private static final int Item_LoadingMoreView = 0; //加载更多布局 private static final int Item_NewsView = 1; //新闻布局 private static final int Item_SliderView = 2; //轮播图片布局 // private static final int Item_ImageNewsView = 2;
2.在创建Adapter时重写getItemViewType方法。根据position返回不同的布局类型参数
/** * 根据position 返回不同的布局类型参数 * @param position * @return */ @Override public int getItemViewType(int position) { // Log.d(TAG,"getItemViewType---position="+position); // Log.d(TAG,"getItemViewType---isloadingmore="+isloadingmore); // Log.d(TAG,"getItemViewType---getItemCount="+getItemCount()); List<Newsbean.adsBean> adsBeanList =new ArrayList<Newsbean.adsBean>(); //用来存储图片新闻对象 for(int i =0; i<listnews.size(); i++){ if(listnews.get(i).getAds()!=null && listnews.get(i).getAds().size()!=0){ adsBeanList = listnews.get(i).getAds(); } } if(position==0 && adsBeanList.size()!=0){ //对于图片新闻,通过轮播的一个布局来实现显示 return Item_SliderView; }else if(isloadingmore && ( position == getItemCount()-1)){ //如果是当前获取来新闻的最后一个,则显示加载更多 布局 return Item_LoadingMoreView; } // else if(listnews.get(position).getAds()!=null && listnews.get(position).getAds().size()!=0){ // return Item_ImageNewsView; // } else{ //否则显示正常新闻布局 return Item_NewsView; } }
3.创建对应的item布局文件,并根据相应布局,去创建对应的RecyclerView.ViewHolder子类
<?xml version="1.0" encoding="utf-8"?> <!--轮播布局--> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.daimajia.slider.library.SliderLayout android:id="@+id/sliderLayout" android:layout_width="match_parent" android:layout_marginTop="3dp" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_height="170dp"> </com.daimajia.slider.library.SliderLayout> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <!--新闻Item--> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" app:cardCornerRadius="8dp" app:cardElevation="5dp" app:contentPadding="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/image" android:layout_width="80dp" android:layout_height="80dp" android:layout_marginLeft="10dp" android:background="@drawable/aboutme"/> <TextView android:id="@+id/newstitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_toRightOf="@+id/image" android:lines="2" android:textSize="18sp" android:textColor="@color/alpha_90_black" android:text="习近平:吹响建设科技强国号角国号角国号角" /> <TextView android:id="@+id/summary" android:layout_width="match_parent" android:layout_height="20dp" android:layout_toRightOf="@+id/image" android:layout_alignLeft="@+id/newstitle" android:layout_below="@+id/newstitle" android:text="科技是国之利器,中国人民生活要好,必须有强大科技。" android:singleLine="true" android:textColor="@color/alpha_70_black" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_below="@+id/summary" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:text="09/10/22" android:singleLine="true" android:textColor="@color/alpha_50_black" /> </RelativeLayout> </android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?> <!--加载更多 布局--> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.wang.avi.AVLoadingIndicatorView android:id="@+id/avloading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" app:indicatorName="PacmanIndicator" app:indicatorColor="@color/colorPrimary"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在加载中,请稍后" android:layout_centerHorizontal="true" android:layout_below="@+id/avloading"/> </RelativeLayout> </android.support.v7.widget.CardView>
class MyViewHolder extends RecyclerView.ViewHolder{ public TextView title; public ImageView imageView; public TextView summary; public TextView time; public MyViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.newstitle); imageView = (ImageView) itemView.findViewById(R.id.image); summary = (TextView) itemView.findViewById(R.id.summary); time = (TextView) itemView.findViewById(R.id.time); } } class MyLoadingViewHolder extends ViewHolder{ public MyLoadingViewHolder(View itemView) { super(itemView); } } class MySliderViewHolder extends ViewHolder{ public SliderLayout sliderLayout; public MySliderViewHolder(View itemView) { super(itemView); sliderLayout = (SliderLayout) itemView.findViewById(R.id.sliderLayout); } }
4.在重写的onCreateViewHolder方法中,根据传入的viewType去将对应的布局文件生成View对象,最终返回对应创建好的ViewHolder对象
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Log.d(TAG,"viewType==="+viewType); if (viewType == Item_LoadingMoreView){ View view = LayoutInflater.from(context).inflate(R.layout.item_loadingmore_layout,parent,false); MyLoadingViewHolder myLoadingViewHolder = new MyLoadingViewHolder(view); return myLoadingViewHolder; }else if (viewType == Item_NewsView){ View view = LayoutInflater.from(context).inflate(R.layout.item_news_layout,parent,false); final MyViewHolder myViewHholder = new MyViewHolder(view); myViewHholder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemsOnClicklistener.onItemOnClick(v,myViewHholder.getLayoutPosition()); } }); return myViewHholder; } else if(viewType == Item_SliderView){ View view = LayoutInflater.from(context).inflate(R.layout.item_sliderview_layout, parent, false); MySliderViewHolder mySliderViewHolder =new MySliderViewHolder(view); return mySliderViewHolder; } // else if (viewType == Item_ImageNewsView){ // View view =LayoutInflater.from(context).inflate(R.layout.item_imagenews_layout,parent, false); // final MyImageViewHolder myImageViewHolder =new MyImageViewHolder(view); // myImageViewHolder.itemView.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // onItemsOnClicklistener.onItemOnClick(v,myImageViewHolder.getLayoutPosition()); // } // }); // return myImageViewHolder; // } return null; }
5.最后在onBindViewHolder方法中进行对应数据的展示
@Override public void onBindViewHolder(final ViewHolder holder, final int position) { // myViewHholder = holder; if(holder instanceof MyViewHolder){ final MyViewHolder myViewHolder = (MyViewHolder) holder; myViewHolder.title.setText(listnews.get(position).getTitle()); myViewHolder.summary.setText(listnews.get(position).getDigest()); myViewHolder.time.setText(listnews.get(position).getPtime()); //根据对应url,加载图片 RxJavaUtil.getimage(context, listnews.get(position).getImgsrc(), new RxJavaUtil.Callback_getImage() { @Override public void sucess(Drawable drawable) { if(drawable!=null){ // Drawable drawable =new BitmapDrawable(bitmap); myViewHolder.imageView.setBackgroundDrawable(drawable); } } @Override public void sucess(String src, Drawable bitmap) { } @Override public void faile() { } }); } else if(holder instanceof MySliderViewHolder){ initSliderLayout((MySliderViewHolder) holder); } }
下面说下关于下拉刷新和上拉加载更多功能的实现。
1. 下拉刷新比较简单,直接通过官方提供的SwipeRefreshLayout控件,将SwipeRefreshLayout作为RecyclerView的上层控件,如下:
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefresh" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview_news" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v7.widget.RecyclerView> </android.support.v4.widget.SwipeRefreshLayout>然后在java代码中进行对应配置
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh); swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary); //设置下拉刷新进度条的颜色 //设置下拉刷新监听事件 swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { getnewsinfo(0, LoadingType_refresh); } });
//监听,RecyclerView的滑动 recyclerview_news.addOnScrollListener(new RecyclerView.OnScrollListener() { //实现上拉加载更多 //滚动状态变化时回调 状态 @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { //newState: //RecyclerView.SCROLL_STATE_FLING; //屏幕处于甩动状态 // RecyclerView.SCROLL_STATE_IDLE; //停止滑动状态 // RecyclerView.SCROLL_STATE_TOUCH_SCROLL;// 手指接触状态 RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); //获取到当前可见的最后一个Item对应的psition int lastposition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); int visiblecount = layoutManager.getChildCount(); //获取当前在页面显示出来的Item的个数,这个值不是固定的。 int itemcount = layoutManager.getItemCount(); //获取当前总的Item个数 if(visiblecount!=0 && newState==RecyclerView.SCROLL_STATE_IDLE &&lastposition==itemcount-1){ newsAdapter.showloadingmore(); //更新列表,显示Item加载布局 handler.postDelayed(new Runnable() { @Override public void run() { //获取更多新闻信息 pagecount = pagecount+20; getnewsinfo(pagecount, LoadingType_more); } },1500); } } //滚动时回调 过程 @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } });