android新闻客户端报告,简易的Android新闻客户端

学完Android基础之后不知道该怎么办?现在开始实战吧!

现在来看看一款简易的Android新闻客户端是怎么做的,当然,获取网络数据的这一部分我是使用别人做好的本地客户端,然后通过组建本地数据库来使用的,这一部分我就不详细介绍了。

本文Demo的地址

https://github.com/liaozhoubei/NetNewsDemo

本篇文章的技术要点:

ListView适配器的使用

Handler的消息发送

SQLite的使用

JSon数据的解析

网络与IO流的使用

做个简易新闻客户端的难度并不大,只要想通了其中的几个要点,做起来就很简单。

制作流程

1、首先需要确定一个listView的布局

2、然后找到listView,设置条目的点击事件

3、获取网络数据给listView做展示

4、创建一个BaseAdapter的子类,接收获取的新闻数据

5、将adapter设置给ListView

现在让我们开始做这个新闻客户端吧!

客户端布局

我们先看看说要获取的JSon数据中拥有什么条目:

{

"newss": [

{

"id": 2,

"time": "2015-08-07",

"des": "7月29日,历经9个月数百万人内测完善之后,微软终于发布Win10正式版系统。但是可能对于部分用户而言,Win7仍然是绝对的经典、游戏玩家的不二之选,为何非要升级到Win10系统呢?Windows10性能和功能相比Windows7,有提升吗?下面IT之家就为大家带来Win7与Win10功能与性能的正面PK,相信还在犹豫不决的用户看完本文心里就会有了答案。",

"title": "升还是不升:Win7、Win10全面对比评测",

"news_url": "http://toutiao.com/a5229867988/",

"icon_url": "http://p2.pstatp.com/large/6850/6105376239",

"comment": 5000,

"type": 1

}

]

}

OK,我们发现JSon新闻数据中要包含这几个类别:

id:新闻的ID号

time:新闻发布的时间

des: 新闻的内容

time:新闻的标题

news_url:新闻的链接地址

icon_url:新闻图片的链接地址

comment: 新闻的评论数

type:新闻是属于那种类别,0 是头条新闻, 1为娱乐新闻,2为体育新闻

因此我们的布局界面应该如下:

88cf805810da?appinstall=0

news.png

在开始写ListView之前我们需要先写出获取新闻的bean对象,每个对象都有get和set方法,由于篇幅有限就省略了一部分,代码如下:

public class NewsBean {

private int id;

private int comment;

private int type;

private String time;

private String title;

private String news_url;

private String icon_url;

private String des;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

·····

}

然后是ListView每个Item的布局,相信布局这方面的内容难不倒大家,所以也缩写了一部分如下

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal" >

android:id="@+id/item_img_icon"

··· />

···

android:orientation="vertical" >

android:id="@+id/item_tv_title"

··· />

android:id="@+id/item_tv_des"

···/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center" >

android:id="@+id/item_tv_comment"

···/>

android:id="@+id/item_tv_type"

··· />

其中有个的控件,这个是自定义的从网络中获取图片的视图控件。

然后我们要设置adapter适配器放置到ListView中去,所以我们先去完成适配器吧!

NewsAdapter

继承BaseAdapter的NewsAdapter需要有这两个成员变量

private LayoutInflater mLayoutInflater;

private List mDatas; // 获取到的新闻集合

还需要一个构造器获取传递过来的数据

public NewsAdapter(Context context, List listNewsBean){

this.mLayoutInflater = LayoutInflater.from(context);

this.mDatas = listNewsBean;

}

然后在重写继承的4个方法

@Override

public int getCount() {

return mDatas.size();

}

@Override

public Object getItem(int position) {

return mDatas.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder viewHolder;

if (convertView == null) {

convertView = mLayoutInflater.inflate(R.layout.layout_item, null);

viewHolder = new ViewHolder();

viewHolder.item_img_icon = (MyImageView) convertView.findViewById(R.id.item_img_icon);;

viewHolder.item_tv_des = (TextView) convertView.findViewById(R.id.item_tv_des);

viewHolder.item_tv_title = (TextView) convertView.findViewById(R.id.item_tv_title);

viewHolder.item_tv_comment = (TextView) convertView.findViewById(R.id.item_tv_comment);

viewHolder.item_tv_type = (TextView) convertView.findViewById(R.id.item_tv_type);

convertView.setTag(viewHolder);

} else{

viewHolder = (ViewHolder) convertView.getTag();

}

NewsBean newsBean= mDatas.get(position);

viewHolder.item_img_icon.setImageUrl(newsBean.getIcon_url());

viewHolder.item_tv_des.setText(newsBean.getDes());

viewHolder.item_tv_title.setText(newsBean.getTitle());

viewHolder.item_tv_comment.setText(newsBean.getComment() + "");

//0 :头条 1 :娱乐 2.体育

switch (newsBean.getType()) {

case 0:

viewHolder.item_tv_type.setText("头条");

break;

case 1:

viewHolder.item_tv_type.setText("娱乐 ");

break;

case 2:

viewHolder.item_tv_type.setText("体育");

break;

default:

break;

}

return convertView;

}

class ViewHolder{

MyImageView item_img_icon;

TextView item_tv_des;

TextView item_tv_title;

TextView item_tv_comment;

TextView item_tv_type;

}

这样整个ListView的adapter对象就弄好了,现在只需要在activity_main.xml中加入ListView视图,然后在MainActivity.java绑定ListView就可以了。

自定义视图

布局现在还没写好,因为我们还有一个获取网络图片的自定义视图没搞好,现在来解决它吧。

自定义视图继承自ImageView,需要继承两个构造方法:

public MyImageView(Context context) {

super(context);

}

public MyImageView(Context context, AttributeSet attrs) {

super(context, attrs);

}

我们从json数据中获取的只是网络图片的url地址,因此我们还需要将网络流转换为地址,然后通过Message将图片发送到主线程中,以避免在子线程更新UI线程

private Handler mHandler = new Handler() {

public void handleMessage(android.os.Message msg) {

Bitmap bitmap = (Bitmap) msg.obj;

MyImageView.this.setImageBitmap(bitmap);

};

};

public void setImageUrl(final String urlString) {

new Thread(new Runnable() {

@Override

public void run() {

try {

URL url = new URL(urlString);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(5 * 1000);

int code = conn.getResponseCode();

if (code == 200) {

InputStream is = conn.getInputStream();

Bitmap bitmap = BitmapFactory.decodeStream(is);

Message message = Message.obtain();

message.obj = bitmap;

mHandler.sendMessage(message);

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}).start();;

}

详细的MyImageView类还是看我的项目代码吧,哈哈!

好了,现在整个视图的布局就完成了,剩下的就是将获取网络数据放在适配器中就可以了

获取网络数据

在获取网络数据之前,我们先编写一个工具类,将InputStream流直接转换为String字符串输出的工具类,代码如下:

public class StreamUtils {

public static String convertStream(InputStream is) {

String result = "";

ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] bt = new byte[1024];

int len = 0;

try {

while ((len = is.read(bt)) != -1) {

bos.write(bt, 0, len);

bos.flush();

}

result = new String(bos.toByteArray(), "utf-8");

result = bos.toString();

bos.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return result;

}

}

现在终于可以正式的获取网络中的json数据了,这个类中写一个getNetNews方法,传出Context和URL参数,返回ArrayList集合类型。

对于JSon数据,我们研究可以得知,它是一个JSONObject,里面包含一个newss的JSONArray数组,数组里面在包含着一个个新闻对象。

整个获取网络数据并解析json数据的方法如下:

public static ArrayList getNetNews(Context context, String urlString) {

ArrayList arraylistNews = new ArrayList();

try {

URL url = new URL(urlString);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(20 * 1000);

int responseCode = conn.getResponseCode();

if (responseCode == 200) {

// 获取请求到的流信息

InputStream is = conn.getInputStream();

// 通过之前的建立的StreamUtils工具类转换流信息

String result = StreamUtils.convertStream(is);

JSONObject root_json = new JSONObject(result);

JSONArray jsonArray = root_json.getJSONArray("newss");

for (int i = 0; i < jsonArray .length(); i ++ ){

JSONObject news_json = jsonArray.getJSONObject(i);

NewsBean newsBean = new NewsBean();

newsBean.setId(news_json.getInt("id"));

newsBean.setTime(news_json.getString("time"));

newsBean.setDes(news_json.getString("des"));

newsBean.setTitle(news_json.getString("title"));

newsBean.setNews_url(news_json.getString("news_url"));

newsBean.setIcon_url(news_json.getString("icon_url"));

newsBean.setComment(news_json.getInt("comment"));

newsBean.setType(news_json.getInt("type"));

arraylistNews.add(newsBean);

}

is.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return arraylistNews;

}

补全MainActivity

所有的工具都写完了,我们可以返回补全MainAcitivty了,在MainActivity中有个Handler,它将网络中返回的json数据反正NewsAdapter总,然后更新ListView中的数据。

private static String result = "傳入包含Json數據的網頁URL";

private Handler mHandler = new Handler() {

public void handleMessage(android.os.Message msg) {

listNewsBean = (List) msg.obj;

NewsAdapter newsAdapter = new NewsAdapter(MainActivity.this, listNewsBean);

listview.setAdapter(newsAdapter);

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mContext = MainActivity.this;

listview = (ListView) findViewById(R.id.list_news);

newsUtils = new NewsUtils();

new Thread(new Runnable() {

@Override

public void run() {

listNewsBean = newsUtils.getNetNews(mContext, result);

Message message = Message.obtain();

message.obj = listNewsBean;

mHandler.sendMessage(message);

}

}).start();

listview.setOnItemClickListener(this); // 设置listView的点击事件,略过

}

基本的新闻客户端设置就到此结束了,但是这只是一个非常简单的客户端,如果是真实的新闻客户端还有很多事情需要做,如设置新闻缓存,当客户端没有联网的时候从数据库中获取新闻等。

现在也顺便写一下如何用数据库缓存新闻吧!

使用SQLite数据库缓存新闻。

使用SQLite需要一个SQLiteOpenHelper类,然后自己封装一个SQLite操作类。

SQLiteOpenHelper类用于建立数据库,并且设置数据库的列表形式,SQLite操作类这是负责数据库的增删查改等工作。

SQLiteOpenHelper类代码如下:

public class NewsDBHelper extends SQLiteOpenHelper{

public NewsDBHelper(Context context) {

super(context, "NetNews", null, 1);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL("create table news (_id integer, title varchar(200), des varchar(300), "

+ "icon_url varchar(100), news_url varchar(200), type integer, time varchar(100), comment integer)");

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// TODO Auto-generated method stub

}

}

SQLite操作类代码如下:

public class NewsDBUtils {

private NewsDBHelper dbHelper;

public NewsDBUtils (Context context) {

dbHelper = new NewsDBHelper(context);

}

// 保存新闻到数据库中

public void saveNews(ArrayList arrayList) {

SQLiteDatabase sqLite = dbHelper.getWritableDatabase();

for(NewsBean newsBean : arrayList) {

ContentValues value = new ContentValues();

value.put("_id", newsBean.getId());

value.put("time", newsBean.getTime());

value.put("des", newsBean.getDes());

value.put("title", newsBean.getTitle());

value.put("news_url", newsBean.getNews_url());

value.put("icon_url", newsBean.getIcon_url());

value.put("comment", newsBean.getComment());

value.put("type", newsBean.getType());

sqLite.insert("news", null, value);

}

sqLite.close();

}

// 删除数据库数据

public void deleteNews (){

SQLiteDatabase db = dbHelper.getReadableDatabase();

db.delete("news", null, null);

db.close();

}

// 从数据库中获取存储的行为

public ArrayList getNews() {

ArrayList arrayList = new ArrayList();

SQLiteDatabase db = dbHelper.getReadableDatabase();

Cursor cursor = db.query("news", null, null, null, null, null, null, null);

if (cursor != null && cursor.getCount() > 0) {

while (cursor.moveToNext()) {

NewsBean newsBean = new NewsBean();

newsBean.setId(cursor.getInt(0));

newsBean.setTime(cursor.getString(1));

newsBean.setDes(cursor.getString(2));

newsBean.setTitle(cursor.getString(3));

newsBean.setNews_url(cursor.getString(4));

newsBean.setIcon_url(cursor.getString(5));

newsBean.setComment(cursor.getInt(6));

newsBean.setType(cursor.getInt(7));

arrayList.add(newsBean);

}

}

return arrayList;

}

}

返回修改获取网络数据类NetUtils和MainActivity类

修改NetUtils在getNetNews的InpuStream流关闭之前(is.close())添加两行代码:

// 如果获取到网络上的数据,就删除之前获取的新闻数据,保存新的新闻数据

new NewsDBUtils(context).deleteNews();

new NewsDBUtils(context).saveNews(arraylistNews);

然后给NetUtils添加一个获取数据库缓存新闻的方法:

// 返回数据库缓存到的数据

public static ArrayList getDBNews(Context context){

return new NewsDBUtils(context).getNews();

}

OK,最后就是修改MainActivity中的代码了,我们需要在onCreate()开启新线程,获取网络数据之前,从数据库中获取到之前缓存的新闻,这样才不会在网速缓慢的时候界面空白一片,增加一些代码:

// 1.先去数据库中获取缓存的新闻数据展示到listview

ArrayList allnews_database = NewsUtils.getDBNews(mContext);

if (allnews_database != null && allnews_database.size() > 0) {

// 创建一个adapter设置给listview

NewsAdapter newsAdapter = new NewsAdapter(mContext, allnews_database);

listview.setAdapter(newsAdapter);

}

总结

一个简易的网络新闻客户端的制作流程就写到这里,可能凌乱了一下,但是结合我在github的代码还是能够看明白的。

另外如果需要这个新闻客户端获取本地web服务方面的代码,也可以联系我。

最后就是如果哪位高手发现我的代码还有改进的地方,还请不吝赐教~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/64107.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于计算机应用技术的周记,计算机应用技术专业实习周记范文

计算机应用技术专业实习周记范文 第1周 作为计算机应用技术专业的大学生&#xff0c;我很荣幸能够进入计算机应用技术专业相关的岗位实习。相信每个人都有第一天上班的经历&#xff0c;也会对第一天上班有着深刻的感受及体会。尤其是从未有过工作经历的职场大学们。 头几天实习…

顶岗周记篇通用计算机,计算机实习周记20篇

2014年 1 月17 日 星期五 实习地点&#xff1a;XXXX 实习主要项目和内容&#xff1a; 这是我实习的第一周&#xff0c;在这一周内因我新来的缘故&#xff0c;只是打字&#xff0c;整理办公室&#xff0c;收集一下一些资料等零事。 主要收获与体会&#xff1a; 春去秋来&#xf…

java实习周记_java程序员的实习周记

java程序员的实习周记 第一周 XML:概念:可扩展的标记语言、优点:结构化,平台、语言无关,标准的 XML读写XML格式的文档,完成数据交换、声明:大多数XML文档以XML声明作为开始、建议使用XML声明,但它不是必需的。如果有,它一定是文档的第一行内容。、注释、实体:不能直接…

技校学生计算机周记,技校学生周记

技校学生周记 导语&#xff1a;社会发展&#xff0c;科技进步&#xff0c;新时代的学生有了很多的变化。他们要比以往的学生要更老练&#xff0c;独立思考的能力也有所加强&#xff0c;以下是小编为大家整理的技校学生周记&#xff0c;欢迎大家阅读与借鉴&#xff01; 技校学生…

关于原型(周记)

1.函数的prototype属性&#xff1a; 1&#xff09;每个函数都有一个prototype属性&#xff0c;它默认指向一个object空对象&#xff08;称作&#xff1a;原型对象&#xff09;&#xff1b; 2&#xff09;原型有一个属性constructor&#xff0c;它指向函数对象&#xff1b; 3…

Langchain 集成 Milvus

Langchain 集成 Milvus 1. 安装 Docker2. 部署 Milvus3.4. Langchain 集成 Milvus 1. 安装 Docker refer: https://docs.docker.com/engine/install/centos/ Milvus 会以容器方式启动&#xff0c;所以先安装 Docker。(本示例使用的是 Alma Linux 9.2) 卸载旧版本&#xff0c…

仿微信界面开发的聊天软件和聊天客户端功能介绍

系统模式&#xff1a;独立系统版本&#xff0c;独立服务器部署&#xff0c;服务器配置&#xff1a;建议 4 核 8G&#xff1b;10M 带宽既可 以下是聊天系统客户端的功能介绍&#xff0c;服务端的功能我会再写一篇文章接着 仿微信聊天开发的聊天软件以及聊天客户端功能介绍插图 …

h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器

之前做过一版h5微信聊天移动端&#xff0c;这段时间闲来无事就整理了下之前项目&#xff0c;又重新在原先的那版基础上升级了下&#xff0c;如是就有了现在的h5仿微信聊天高仿版&#xff0c;新增了微聊、通讯录、探索、我四个模块 左右触摸滑屏切换&#xff0c;聊天页面优化了多…

Android 高仿微信实时聊天 基于百度云推送

转载请标明出处&#xff1a;http://blog.csdn.net/lmj623565791/article/details/38799363 &#xff0c;本文出自&#xff1a;【张鸿洋的博客】 一直在仿微信界面&#xff0c;今天终于有幸利用百度云推送仿一仿微信聊天了~~~ 首先特别感谢:weidi1989分享的Android之基于百度云…

LSTM笔记

RNN, LSTM, GRU模型的作用, 构建, 优劣势比较,attention机: https://blog.csdn.net/sinat_28015305/article/details/109355828?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167903492816800182195114%2522%252C%2522scm%2522%253A%252220140713.130102334..%252…

手把手教你生成正式签名的APK文件

一&#xff0c;使用Android Studio生成 1. 2. 3.如果先前没有则先点Create new 4. 5. 6. 7.点击Finish 8. 二.使用Gradle生成&#xff1a; 1.在安卓闭包中加上 上图紫色字体跟第一种生成方式填的内容一样&#xff0c;这里我把它隐藏起来了 注&#xff1a;一定要放在buildTy…

Android购物软件制作(毕业设计)

本篇博客为了展示自己的实战结果&#xff0c;完成了对淘宝功能的实现&#xff0c;主要用于毕业设计的完成。 首先贴图以表效果&#xff0c;虽然拉跨&#xff0c;但是毕业够用&#xff01; 首先&#xff1a;要开发一款淘宝类的APP&#xff0c;其实分为两种&#xff0c;一种是淘…

[干货]手把手教你写一个安卓app

摘要&#xff1a;最近有很多小伙伴在后台留言&#xff1a;Android Studio。我想大家是想写一个手机app&#xff0c;前面已经分享了在QT上如何写一个安卓蓝牙app&#xff0c;虽然qt可以做app&#xff0c;但是比起Android Studio还是差很多。这里介绍一种快速入门的方法来制作一款…

Android手机通讯录制作

Android手机通讯录制作 要求样图展示代码1.创建数据库2.主界面MainActivityCustomAdapter.javaactivity_main.xml 3.添加联系人AddContacts.java(添加界面)addactivity.xml 要求 设计一个基于Android的手机通讯录&#xff0c;此通讯录包括添加、搜索、修改、删除联系人的功能。…

安卓APP源码和设计报告——个人通讯录

摘 要 随着移动设备制造技术和移动通信网络的迅猛发展,全球手机用户日益增加,手机成为了很多人日常生活中必不可少的一部分,手机业在日益发展的同时,人们对手机的功能需求和体验需求也越来越高,因此各种智能手机相继而出&#xff0c;当前市场上最流行的智能手机的操作系统非An…

【视觉基础篇】12 # 如何使用滤镜函数实现美颜效果?

说明 【跟月影学可视化】学习笔记。 如何理解像素化&#xff1f; 像素化 所谓像素化&#xff0c;就是把一个图像看成是由一组像素点组合而成的。每个像素点负责描述图像上的一个点&#xff0c;并且带有这个点的基本绘图信息。 像素点是怎么存储的&#xff1f; Canvas2D 以…

C++ / Opencv 简单实现美颜效果(瘦脸、大眼、磨皮等)

最近项目需要用到美颜的一些效果&#xff0c;因此开始接触opencv 计算机视觉库,在腾讯课堂上找到一个简单且免费的入门视频《Opencv4 快速入门视频30讲》&#xff0c;看完视频后&#xff0c;初步才对opencv 有一个比较清晰的概念和基本用法。 接下来就是开始对美颜的一些初步接…

Ps人像磨皮皮肤美白插件哪个好_安装教程

今天这个PS插件挺好用的&#xff0c;我们可以用它快速给人像照片磨皮、皮肤美白、上妆等功能&#xff0c;还是非常方便我们后期修图的&#xff0c;有需要这个插件的可以至陌鱼社区瞧一下。插件支持:Adobe PhotoshopCC2015 - CC2018,这里我们用Adobe PhotoshopCC2018做为演示&am…

对皮肤美白算法的一些研究

本篇博文来自博主Imageshop&#xff0c;打赏或想要查阅更多内容可以移步至Imageshop。 转载自&#xff1a;https://www.cnblogs.com/Imageshop/p/3843635.html 侵删 皮肤美白是现在任何一款流行的美颜软件必备的功能之一&#xff0c;不过你如果在互联网上搜索关于美白算法&a…

Portraiture4.0最新PS专属修图磨皮美白插件

作为PS的插件&#xff0c;被众多照片后期高手使用&#xff0c;评价颇高。主要原因在于它操作简便、磨皮效果好、软件很小&#xff0c;特别是它可以自动感应皮肤区域磨皮&#xff0c;只对皮肤作用更令人称奇的是&#xff1a;Portraiture 磨皮能保留下细小的毛孔和皮肤质感&#…