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实体类代码:
主布局main_acitivity.xml代码:
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; }}
<?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>
给大家总结一下:
- 导入上拉加载跟多下拉刷新控件CommonPullToRefresh和RecyclerView控件。
- 编写item布局,有多少种item就编写多少种。
- 在下拉刷新上拉加载更多控件中嵌套RecyclerView控件
- 在主布局中实例化2个控件,并且重写CommonPullToRefresh的一些方法,具体的看该控件的用法,github项目中有用法说明,详情上拉加载更多下拉刷新控件的用法
- 编写RecyclerView适配器。
- 根据list传入的数据获取item的类型。
- 根据item类型编写不同的ViewHolder。
- 根据不同的ViewHolder进行数据和行为的绑定。
阅读全文
0 1
- Android实现新闻效果原来如此简单
- android代码混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- android 代码 混淆- 原来如此简单
- Android实现腾讯新闻的新闻类别导航效果
- Android实现网易新闻客户端效果
- android listview实现新闻列表展示效果
- 原来如此简单
- Android Studio集成jni so原来如此简单
- Android热修复之 - 打补丁原来如此简单
- Android网易新闻评论盖楼效果的实现
- Android网易新闻评论盖楼效果的实现
- 知晓当前活动和随时退出活动
- laravel框架学习(二) 解决MySQL5.7以下数据无法迁移的方法
- Android源码基础解析之Dialog加载绘制流程
- eclipse git插件 上传新项目到码云库
- MQ消息中间件技术
- Android实现新闻效果原来如此简单
- java生成登录验证码
- java之log4j的配置
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 线程池
- 如何保证数据安全性?【讨论】
- tomcat部署静态html网站方法
- 2017安卓技术大会:包括Android设计与架构
- ns3安装,更新源问题与解决