Android实现新闻效果原来如此简单

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21004057/article/details/78283160

大家好,本篇文章教大家如何实现一个类似今日头条的效果。如果您熟悉RecyclerView的用法那么本篇文章会提供一个思路,如果您不会RecyclerView。本篇文章也会带你学习它。同时,在本文中您将会学会如何上拉加载,下拉刷新控件的用法。本文效果不仅仅限于新闻效果,同时比如购物列表,动态列表等效果都可以用本思路实现。效果图如下:


本文的知识点如下:

一:RecycerView+CommonPullToRefresh的实现上拉加载下拉刷新

二:每个item根据不同的类型加载不同的布局

三:解析JSON数据设置到每个item上


第一步:编写几种不同类型type的item布局

我们知道新闻列表有好几种item类型。本文只编写了2种布局,真正的新闻列表可能还包括视频布局,图集新闻等多种item类型。不过咱们以不变应万变,再多的item类型也不用担心。




单图文布局recyclerview_item_type_02.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <LinearLayout
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:id="@+id/tx_news_simple_photos_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:maxLines="2"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingTop="5dp"
            android:text="你没有看错!8天长假赴韩中国团体游客数量为0"
            android:textColor="#696969"
            android:textSize="18sp"
            android:textStyle="bold" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="10dp"
            android:paddingLeft="10dp"
            >
            <TextView
                android:id="@+id/tx_news_simple_photos_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1小时前" />

            <TextView
                android:id="@+id/img_news_simple_photos_author"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:text="新闻集锦" />
        </LinearLayout>
    </LinearLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        >
        <ImageView
            android:id="@+id/tx_news_simple_photos_01"
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/t01abe4bc24227b205b"
            />

    </RelativeLayout>
</LinearLayout>

效果如下:


多图文布局recyclerview_item_type_01.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >
    <TextView
        android:id="@+id/tx_news_mul_photos_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:text="你没有看错!8天长假赴韩中国团体游客数量为0"
        android:maxLines="2"
        android:textStyle="bold"
        android:textSize="18sp"
        android:textColor="#696969"
        />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/img_news_mul_photos_01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:src="@drawable/t01abe4bc24227b205b" />

        <ImageView
            android:id="@+id/img_news_mul_photos_02"
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:src="@drawable/am" />

        <ImageView
            android:id="@+id/img_news_mul_photos_03"
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:src="@drawable/t01d931300dd6f99783" />
    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="10dp"
        android:layout_marginTop="10dp"
        >
        <TextView
            android:id="@+id/tx_news_mul_photos_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1小时前"
            />
        <TextView
            android:id="@+id/tx_news_mul_photos_author"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/tx_news_mul_photos_time"
            android:text="新闻集锦"
            android:layout_marginLeft="20dp"
            />
    </RelativeLayout>
</LinearLayout>

效果图如下:



第二步:添加依赖,导入RecyclerView和CommonPullToRefresh控件

 compile 'com.android.support:recyclerview-v7:24.0.0-alpha1'
 compile 'com.chanven.lib:cptr:1.1.0'


第三步:创建主布局,实例化RecyclerView控件并为其设置Adapter适配器

package com.example.mulrecyclerviewdemo;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;

import com.chanven.lib.cptr.PtrClassicFrameLayout;
import com.chanven.lib.cptr.PtrDefaultHandler;
import com.chanven.lib.cptr.PtrFrameLayout;
import com.chanven.lib.cptr.loadmore.OnLoadMoreListener;
import com.chanven.lib.cptr.recyclerview.RecyclerAdapterWithHF;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private  String strJson="{\"pages\":1,\"data\":[{\"type\":0,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":1,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":0,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":1,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":0,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":1,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":0,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":1,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":0,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\"]},{\"type\":1,\"title\":\"澳大利亚向非洲捐赠1000万美元\",\"time\":\"1小时前\",\"author\":\"卡尔网\",\"imgs\":[\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\",\"http://52sjw.com/images/jasdhisah.img\"]}]}";
    private RecyclerView recyclerView;
    private PtrClassicFrameLayout ptrClassicFrameLayout;
    private Handler handler=new Handler();
    private int page = 0;
    private List<NewsPhotoBean> list = new ArrayList<NewsPhotoBean>();
    private MulRecyclerViewAdapter adapter;
    private RecyclerAdapterWithHF mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_acitivity);
        initView();
        adapter = new MulRecyclerViewAdapter(this,list);
        mAdapter = new RecyclerAdapterWithHF(adapter);
        recyclerView.setAdapter(mAdapter);
        ptrClassicFrameLayout.postDelayed(new Runnable() {

            @Override
            public void run() {
                ptrClassicFrameLayout.autoRefresh(true);
            }
        }, 150);
        ptrClassicFrameLayout.setPtrHandler(new PtrDefaultHandler() {
            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        page= 0;
                        list.clear();
                        try {
                            JSONObject jsonObject = new JSONObject(strJson);
                            JSONArray jsonArray  = jsonObject.getJSONArray("data");
                            for(int i = 0;i<10;i++){
                                NewsPhotoBean newsPhotoBean = new NewsPhotoBean();
                                newsPhotoBean.setType(jsonArray.getJSONObject(i).getInt("type"));
                                newsPhotoBean.setTitle(jsonArray.getJSONObject(i).getString("title"));
                                newsPhotoBean.setF_time(jsonArray.getJSONObject(i).getString("time"));
                                newsPhotoBean.setAuthor(jsonArray.getJSONObject(i).getString("author"));
                                int len = jsonArray.getJSONObject(i).getJSONArray("imgs").length();
                                List<String> ls = new ArrayList<>();
                                for(int j = 0;j<len;j++){
                                    String s = jsonArray.getJSONObject(i).getJSONArray("imgs").getString(j);
                                    ls.add(s);
                                }
                                newsPhotoBean.setList(ls);
                                list.add(newsPhotoBean);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        mAdapter.notifyDataSetChanged();
                        ptrClassicFrameLayout.refreshComplete();
                        ptrClassicFrameLayout.setLoadMoreEnable(true);
                        Log.d("TAG","正在刷新...");
                    }
                }, 1500);
            }
        });
        ptrClassicFrameLayout.setOnLoadMoreListener(new OnLoadMoreListener() {

            @Override
            public void loadMore() {
                handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            JSONObject jsonObject = new JSONObject(strJson);
                            JSONArray jsonArray  = jsonObject.getJSONArray("data");
                            for(int i = 0;i<10;i++){
                                NewsPhotoBean newsPhotoBean = new NewsPhotoBean();
                                newsPhotoBean.setType(jsonArray.getJSONObject(i).getInt("type"));
                                newsPhotoBean.setTitle(jsonArray.getJSONObject(i).getString("title"));
                                newsPhotoBean.setF_time(jsonArray.getJSONObject(i).getString("time"));
                                newsPhotoBean.setAuthor(jsonArray.getJSONObject(i).getString("author"));
                                int len = jsonArray.getJSONObject(i).getJSONArray("imgs").length();
                                List<String> ls = new ArrayList<>();
                                for(int j = 0;j<len;j++){
                                    String s = jsonArray.getJSONObject(i).getJSONArray("imgs").getString(j);
                                    ls.add(s);
                                }
                                newsPhotoBean.setList(ls);
                                list.add(newsPhotoBean);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        mAdapter.notifyDataSetChanged();
                        ptrClassicFrameLayout.loadMoreComplete(true);
                        page++;
                        Log.e("TAG",page+"页");
                        Toast.makeText(MainActivity.this, "加载完成", Toast.LENGTH_SHORT).show();
                    }
                }, 1000);
            }
        });
    }



    private void initView() {
        ptrClassicFrameLayout = (PtrClassicFrameLayout) findViewById(R.id.test_list_view_frame);
        recyclerView = (RecyclerView) findViewById(R.id.news_recycler_view);
        LinearLayoutManager llm =new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
        recyclerView.setLayoutManager(llm);
        recyclerView.addItemDecoration(new RecyclerViewDivider(MainActivity.this, LinearLayoutManager.VERTICAL));

    }

}


第四步:创建RecyclerView的适配器。

package com.example.mulrecyclerviewdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

import static android.R.attr.author;
import static android.R.attr.type;
import static android.R.id.list;
import static android.media.CamcorderProfile.get;

/**
 * Created by chenlei on 2017/10/11.
 */

public class MulRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int NEW_SIMPLE_TYPE = 0;//单图文模式
    private static final int NEW_MUL_TYPE = 1;//多图文模式
    private static final int NEW_OTHER_TYPE = 2;//多图文模式
    private Context context;
    private List<NewsPhotoBean> list;

    MulRecyclerViewAdapter(Context context, List<NewsPhotoBean> list) {
        this.context = context;
        this.list = list;
    }

    //重写getItemViewType方法,通过此方法来判断应该加载是哪种类型布局
    @Override
    public int getItemViewType(int position) {
        int type = list.get(position).getType();
            switch (type) {
                case 0:
                    return NEW_SIMPLE_TYPE;
                case 1:
                    return NEW_MUL_TYPE;
            }
        return NEW_OTHER_TYPE;
    }

    //根据不同的item类型来加载不同的viewholder
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        switch (viewType) {
            case NEW_SIMPLE_TYPE:
                return new NewsPhotoViewHolder(inflater.inflate(R.layout.recyclerview_item_type_02, parent, false));
            case NEW_MUL_TYPE:
                return new NewsPhotosViewHolder(inflater.inflate(R.layout.recyclerview_item_type_01, parent, false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //把对应位置的数据得到
            String title = list.get(position).getTitle();
            String time = list.get(position).getF_time();
            String author = list.get(position).getAuthor();
            List<String> ls = list.get(position).getList();//这里是json数据中的图片集合,也就是封面。不同类型item的封面图片数量是不一样的
      //  //无论是否单图文,标题和更新时间以及作者不变

        //如果单图文
        if (holder instanceof NewsPhotoViewHolder) {

            ((NewsPhotoViewHolder) holder).tx_news_simple_photos_title.setText(title);
            ((NewsPhotoViewHolder) holder).tx_news_simple_photos_time.setText(time);
            ((NewsPhotoViewHolder) holder).tx_news_simple_photos_author.setText(author);
//            ((NewsPhotoViewHolder) holder).img_news_simple_photos_01.setImageBitmap(btm_01);//单图文不用遍历直接将图片转换bitmap对象设置到ImageView上
            return;
        }
        //如果多图文
        if (holder instanceof NewsPhotosViewHolder) {
            ((NewsPhotosViewHolder) holder).tx_news_mul_photos_title.setText(title);
            ((NewsPhotosViewHolder) holder).tx_news_mul_photos_time.setText(time);
            ((NewsPhotosViewHolder) holder).tx_news_mul_photos_author.setText(author);
//            ((NewsPhotosViewHolder) holder).img_news_mul_photos_01.setImageBitmap(btm_01);//多图文需要遍历list将每个图片链接转换成Bitmap对象设置到ImageView上
//            ((NewsPhotosViewHolder) holder).img_news_mul_photos_02.setImageBitmap(btm_02);
//            ((NewsPhotosViewHolder) holder).img_news_mul_photos_03.setImageBitmap(btm_03);
            return;
        }
    }
    //具体item数据等于pages*10,每页10条
    @Override
    public int getItemCount() {

        return list.size();
    }

    /**
     * NewsPhotoViewHolder为单图文模式
     */
    class NewsPhotoViewHolder extends RecyclerView.ViewHolder {
        private TextView tx_news_simple_photos_title;//标题
        private ImageView img_news_simple_photos_01;//单图文模式的唯一一张图
        private TextView tx_news_simple_photos_time;//单图文模式的更新时间
        private TextView tx_news_simple_photos_author;//单图文模式的新闻作者

        public NewsPhotoViewHolder(View itemView) {
            super(itemView);
            tx_news_simple_photos_title = (TextView) itemView.findViewById(R.id.tx_news_simple_photos_title);//标题
//            img_news_simple_photos_01 = (ImageView) itemView.findViewById(R.id.tx_news_simple_photos_01);//单图文模式的唯一一张图
            tx_news_simple_photos_time = (TextView) itemView.findViewById(R.id.tx_news_simple_photos_time);//单图文模式的更新时间
            tx_news_simple_photos_author = (TextView) itemView.findViewById(R.id.img_news_simple_photos_author);//单图文模式的新闻作者

        }
    }

    /**
     * NewsPhotosViewHolder为多图模式
     */
    class NewsPhotosViewHolder extends RecyclerView.ViewHolder {
        private TextView tx_news_mul_photos_title;//标题
//        private ImageView img_news_mul_photos_01;//多图文模式的第一张图
//        private ImageView img_news_mul_photos_02;//多图文模式的第二张图
//        private ImageView img_news_mul_photos_03;//多图文模式的第三张图
        private TextView tx_news_mul_photos_time;//多图文模式的更新时间
        private TextView tx_news_mul_photos_author;//多图文模式的新闻作者

        public NewsPhotosViewHolder(View itemView) {
            super(itemView);
            tx_news_mul_photos_title = (TextView) itemView.findViewById(R.id.tx_news_mul_photos_title);
//            img_news_mul_photos_01 = (ImageView) itemView.findViewById(R.id.img_news_mul_photos_01);
//            img_news_mul_photos_02 = (ImageView) itemView.findViewById(R.id.img_news_mul_photos_02);
//            img_news_mul_photos_03 = (ImageView) itemView.findViewById(R.id.img_news_mul_photos_03);
            tx_news_mul_photos_time = (TextView) itemView.findViewById(R.id.tx_news_mul_photos_time);
            tx_news_mul_photos_author = (TextView) itemView.findViewById(R.id.tx_news_mul_photos_author);
        }
    }
}


第五步:封装每条item的数据到实体类中

NewsPhotoBean.java实体类代码:
package com.example.mulrecyclerviewdemo;

import android.graphics.Bitmap;
import android.widget.ImageView;

import java.util.List;

import static android.R.attr.type;

/**
 * Created by chenlei on 2017/10/11.
 */

public class NewsPhotoBean {

    public List<String> list;//封面图片的集合
    private int type;//排版类型
    private String title;//标题
    private String f_time;//发布时间
    private String author;//作者

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }
    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }


    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }



    public String getF_time() {
        return f_time;
    }

    public void setF_time(String f_time) {
        this.f_time = f_time;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }


}

主布局main_acitivity.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<com.chanven.lib.cptr.PtrClassicFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
    android:id="@+id/test_list_view_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0"
    cube_ptr:ptr_resistance="1.7"
    cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
    cube_ptr:ptr_duration_to_close="200"
    cube_ptr:ptr_duration_to_close_header="1000"
    cube_ptr:ptr_keep_header_when_refresh="true"
    cube_ptr:ptr_pull_to_fresh="false">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/news_recycler_view"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"/>
</com.chanven.lib.cptr.PtrClassicFrameLayout>



给大家总结一下:
  1. 导入上拉加载跟多下拉刷新控件CommonPullToRefresh和RecyclerView控件。
  2. 编写item布局,有多少种item就编写多少种。
  3. 在下拉刷新上拉加载更多控件中嵌套RecyclerView控件
  4. 在主布局中实例化2个控件,并且重写CommonPullToRefresh的一些方法,具体的看该控件的用法,github项目中有用法说明,详情上拉加载更多下拉刷新控件的用法
  5. 编写RecyclerView适配器。
  6. 根据list传入的数据获取item的类型。
  7. 根据item类型编写不同的ViewHolder。
  8. 根据不同的ViewHolder进行数据和行为的绑定。


猜你喜欢

转载自blog.csdn.net/qq_21004057/article/details/78283160