练习项目 一款新闻app的开发 (四):通过RecyclerView来展示新闻列表

接下来整理下以下功能:

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);
            }
        });


2. 关于上拉加载更多,主要是通过监听 RecyclerView的滑动,当滑动到当前Item新闻列表的最后一个时,去显示一个加载更多的进度条布局,同时去访问后面的新闻列表。当访问成功后,将加载更多的进度条布局 隐藏,重新更新列表。

//监听,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);
            }
        });






猜你喜欢

转载自blog.csdn.net/u010057965/article/details/78216617