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

来源:互联网 发布:海信网络机顶盒ip906h 编辑:程序博客网 时间:2024/05/16 15:54

大家好,本篇文章教大家如何实现一个类似今日头条的效果。如果您熟悉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进行数据和行为的绑定。


原创粉丝点击