編輯:關於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 ListnewsList; @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(); } } }
5、Activity用SharedPreferences保存數據,大小有木有限制?個人理解:SharedPreferences是哪種存儲數據的方式竟然記不清楚了,個人印象
Android中的測試無非是分為兩種:一、在一個工程裡面寫測試代碼。二、專門新建一個工程寫測試代碼。一、在一個工程裡面寫測試代碼步驟:1、寫一個類繼承AndroidTes
Android開發中經常使用Handler來實現“跨越線程(Activity)更新UI”。本文將從源碼角度回答:為什麼使用Handler能夠跨線程更新UI?為什麼跨線程更
自定義圓形ImageView圓形ImageView在頭像顯示用的比較普遍了,今天對於實現圓形ImageView做個總結;主要思路是 重寫 onDraw() ;方法有兩個: