練習項目 一款新聞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);
            }
        });






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章