編輯:關於Android編程
前面介紹了在Android中實現網絡通信,這篇文章將是對前面介紹的技術的一個綜合運用,制作一個簡單的新聞客戶端,在這個新聞客戶端中用到了ListView、ListView的優化、使用開源框架訪問網絡圖片、使用pull解析xml文件等技術,這些技術都是前面介紹的。
首先看一下新聞客戶端的演示效果

實現方式:
第一步:將新聞中用到的圖片部署到Tomcat服務器上,部署方法可以參考我的博客:在Windows下安裝Tomcat服務器
第二步:新建一個xml文件用於保存新聞中的標題、新聞的內容、評論數、新聞中圖片所在的地址、xml文件如下
熱烈祝賀黑馬52期平均薪水突破13k 15687 http://192.168.1.101:8080/app/images/6.jpg
凶手是死者同事,維護死者代碼時完全看不懂而痛下殺手 16359 http://192.168.1.101:8080/app/images/7.jpg
凶手是一名程序員,因死者對項目需求頻繁改動而痛下殺手 14112 http://192.168.1.101:8080/app/images/7.jpg
最高法駁回360上訴, 維持一審宣判. 6427 http://192.168.1.101:8080/app/images/1.jpg
市民: 因霧霾起訴環保局; 公務員談"緊日子": 堅決不出去. 681 http://192.168.1.101:8080/app/images/2.jpg
外文局: 國際民眾認可中國大國地位;法院: "流量清零"未侵權. 1359 http://192.168.1.101:8080/app/images/3.jpg
放假時我醒了不代表我起床了, 如今我起床了不代表我醒了! 11616 http://192.168.1.101:8080/app/images/4.jpg
"媽, 我在東莞被抓, 要2萬保釋金, 快匯錢到xxx!" 10339 http://192.168.1.101:8080/app/images/5.jpg
少壯不努力,老大做IT 14612 http://192.168.1.101:8080/app/images/8.jpg
問君能有幾多愁,恰似調完代碼改需求 13230 http://192.168.1.101:8080/app/images/8.jpg
覺得我帥的人工資一般都比較高 9928 http://192.168.1.101:8080/app/images/8.jpg
市民: 因霧霾起訴環保局; 公務員談"緊日子": 堅決不出去. 681 http://192.168.1.101:8080/app/images/2.jpg
外文局: 國際民眾認可中國大國地位;法院: "流量清零"未侵權. 1359 http://192.168.1.101:8080/app/images/3.jpg
title:新聞的標題
detail:新聞的內容
comment:新聞的評論數
image:新聞中圖片所在的網址
創建完後將Xml文件部署到Tomcat服務器上
第三步:使用Android Studio創建一個Android工程
1、修改activity_main.xml文件,在activity_main.xml中添加一個ListView控件
2、新建一個item_listview.xml的布局文件,用於設置ListView中的條目的布局,在這個布局中用到了一個自定義控件
SmartImageView控件。
item_listview.xml中的代碼如下
3、新建一個News類,用於處理新聞中的數據
package com.fyt.newsclient;
//創建一個News類用於處理新聞
public class News {
//新聞的標題
private String title;
//新聞的詳細介紹
private String detai;
//新聞的評論數量
private int comment;
//新聞中圖片的URL
private String imageUrl;
//無參構造
public News() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDetai() {
return detai;
}
public void setDetai(String detai) {
this.detai = detai;
}
public int getComment() {
return comment;
}
public void setComment(int comment) {
this.comment = comment;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageURL(String imageUrl) {
this.imageUrl = imageUrl;
}
@Override
public String toString() {
return "News{" +
"title='" + title + '\'' +
", detai='" + detai + '\'' +
", comment=" + comment +
", imageUrl='" + imageUrl + '\'' +
'}';
}
}
4、修改MainActivity.java中的代碼
package com.fyt.newsclient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Xml;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.loopj.android.image.SmartImageView;
import org.xmlpull.v1.XmlPullParser;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
//用於創建保存新聞的集合
private List newsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲得新聞信息
getNewsInfo();
}
//創建Handler對象,用於在主線程中接收並處理由子線程
//發送過來的消息
Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
//獲得布局文件上的ListView控件
ListView listView = (ListView) findViewById(R.id.lv);
//為ListView控件設置適配器
listView.setAdapter(new MyAdapter());
}
};
//創建一個自定義的適配器類MyAdapter
class MyAdapter extends BaseAdapter {
//設置ListView中條目的個數,由系統調用
@Override
public int getCount() {
return newsList.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
ViewHolder mHolder;
//如果ListView中的條目沒有緩存
if(convertView == null)
{
//將布局文件填充成一個View對象
v = View.inflate(MainActivity.this, R.layout.item_listview, null);
//創建一個ViewHolder對象
mHolder = new ViewHolder();
//把布局文件中所有組件的對象封裝至ViewHolder對象中
mHolder.tv_title = (TextView) v.findViewById(R.id.tv_title);
mHolder.tv_detail = (TextView) v.findViewById(R.id.tv_detail);
mHolder.tv_comment = (TextView) v.findViewById(R.id.tv_comment);
mHolder.siv = (SmartImageView) v.findViewById(R.id.iv);
//把ViewHolder對象封裝至View對象中
v.setTag(mHolder);
}
//ListView中的條目有緩存
else
{
v = convertView;
//從緩存中獲得ViewHolder對象
mHolder = (ViewHolder) v.getTag();
}
//設置新聞的標題
mHolder.tv_title.setText(newsList.get(position).getTitle());
//設置新聞的內容
mHolder.tv_detail.setText(newsList.get(position).getDetai());
//設置評論的數量
mHolder.tv_comment.setText(newsList.get(position).getComment()+"條評論");
//下載並顯示圖片
mHolder.siv.setImageUrl(newsList.get(position).getImageUrl());
return v;
}
class ViewHolder{
//條目的布局文件中有什麼組件,這裡就定義什麼屬性
TextView tv_title;
TextView tv_detail;
TextView tv_comment;
SmartImageView siv;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
//獲得新聞信息
public void getNewsInfo() {
//創建一個子線程
Thread t = new Thread() {
//執行子線程
@Override
public void run() {
//設置新聞所在的xml文件的地址
String path = "http://192.168.1.101:8080/app/news.xml";
try {
//將地址封裝成URL對象
URL url = new URL(path);
//獲取連接對象,此時未建立連接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設置請求方式為Get請求
conn.setRequestMethod("GET");
//設置連接超時
conn.setConnectTimeout(5000);
//設置讀取超時
conn.setReadTimeout(5000);
//如果請求成功
if(conn.getResponseCode() == 200) {
//獲得文件輸入流
InputStream is = conn.getInputStream();
//使用pull解析器解析文件輸入流中的xml文件
parseNewsXml(is);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
//啟動子線程
t.start();
}
//使用pull解析器解析文件輸入流中的xml文件
public void parseNewsXml(InputStream is) {
//創建pull解析器對象
XmlPullParser xp = Xml.newPullParser();
try {
//將輸入流中的數據以utf-8格式輸入到pull解析器
xp.setInput(is, "utf-8");
//判斷節點的事件類型
//可以知道當前節點是什麼節點
int type = xp.getEventType();
//定義一個News變量,用於創建新聞對象
News news = null;
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if("newslist".equals(xp.getName()))
{
newsList = new ArrayList();
}
else if("news".equals(xp.getName()))
{
news = new News();
}
else if("title".equals(xp.getName()))
{
String title = xp.nextText();
news.setTitle(title);
}
else if("detail".equals(xp.getName()))
{
String detail = xp.nextText();
news.setDetai(detail);
}
else if("comment".equals(xp.getName()))
{
int comment = Integer.parseInt(xp.nextText());
news.setComment(comment);
}
else if("image".equals(xp.getName()))
{
String image = xp.nextText();
news.setImageURL(image);
}
break;
case XmlPullParser.END_TAG:
if("news".equals(xp.getName())){
newsList.add(news);
}
break;
}
//解析完當前節點後,把指針移動至下一個節點,並返回它的事件類型
type = xp.next();
}
//發送空消息到主線程並且讓主線程設置listview的適配器
//如果消息不需要攜帶數據,可以發送空消息
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Android面試准備 第二天 第五例 數據存儲
5、Activity用SharedPreferences保存數據,大小有木有限制?個人理解:SharedPreferences是哪種存儲數據的方式竟然記不清楚了,個人印象
Android review Android中的測試
Android中的測試無非是分為兩種:一、在一個工程裡面寫測試代碼。二、專門新建一個工程寫測試代碼。一、在一個工程裡面寫測試代碼步驟:1、寫一個類繼承AndroidTes
Android Handler 詳解
Android開發中經常使用Handler來實現“跨越線程(Activity)更新UI”。本文將從源碼角度回答:為什麼使用Handler能夠跨線程更新UI?為什麼跨線程更
自定義圓形ImageView 實現思路 -- Android 學習之路
自定義圓形ImageView圓形ImageView在頭像顯示用的比較普遍了,今天對於實現圓形ImageView做個總結;主要思路是 重寫 onDraw() ;方法有兩個: