实现一个简单的手机博客客户端的开发
本程序暂时实现以下的功能:
1、首先实现一个去服务器获取一串xml的数据,然后显示到界面上
2、点击图片可以放大查看
最终效果如下:
1、首先把界面写出来,使用listView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/blogLV" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> </LinearLayout>
2.item的界面
<?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="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/portraitIV" android:layout_width="50dp" android:layout_height="50dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="5dp" > <TextView android:id="@+id/nameTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:text="姓名" android:textSize="20sp" /> <TextView android:id="@+id/contentTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:textSize="15sp" /> <ImageView android:id="@+id/picIV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:adjustViewBounds="true" android:maxHeight="100dp" android:maxWidth="100dp" /> <TextView android:id="@+id/fromTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:textColor="#55FFFFFF" android:text="来自新浪博客" android:textSize="15sp" /> </LinearLayout> </LinearLayout>
3、步入正题blog.java
package cn.itcast.blog; public class Blog { private String portrait; private String name; private String content; private String pic; private String from; public Blog() { super(); } public Blog(String portrait, String name, String content, String pic, String from) { super(); this.portrait = portrait; this.name = name; this.content = content; this.pic = pic; this.from = from; } public String getPortrait() { return portrait; } public void setPortrait(String portrait) { this.portrait = portrait; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getPic() { return pic; } public void setPic(String pic) { this.pic = pic; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } @Override public String toString() { return "Blog [portrait=" + portrait + ", name=" + name + ", content=" + content + ", pic=" + pic + ", from=" + from + "]"; } }
4.主界面mainActivity
package cn.itcast.blog; import java.util.List; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class mainActivity extends Activity { private ListView blogLV; private List<Blog> blogs; private ImageService imageService; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { imageService = new ImageService(getApplicationContext()); // 图片业务类 BlogService blogservice=new BlogService(); // 博客业务类 blogs = blogservice.getBlogs(); // 获取博客数据 blogLV = (ListView) this.findViewById(R.id.blogLV); // 获取ListView blogLV.setAdapter(adapter); //设置适配器,构建界面 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Toast.makeText(this, "服务器忙", 0).show(); } } //创建出来一个adapter,构建出了一个界面 private BaseAdapter adapter=new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) { //用blog中的数据来替换view中的数据 View view =convertView==null?View.inflate(getApplicationContext(), R.layout.item, null):convertView; ImageView portraitIV = (ImageView) view.findViewById(R.id.portraitIV); TextView nameTV = (TextView) view.findViewById(R.id.nameTV); TextView contentTV = (TextView) view.findViewById(R.id.contentTV); ImageView picIV = (ImageView) view.findViewById(R.id.picIV); TextView fromTV = (TextView) view.findViewById(R.id.fromTV); final Blog blog = blogs.get(position); // 获取指定位置上的博客 nameTV.setText(blog.getName()); // 设置文本数据 contentTV.setText(blog.getContent()); fromTV.setText(blog.getFrom()); //设置图片资源的显示位置 try { portraitIV.setImageBitmap(imageService.getImage(blog.getPortrait())); // 根据地址获取图片, 设置图片 } catch (Exception e) { e.printStackTrace(); } //设置一个功能是实现图片点击放大的功能 try { picIV.setImageBitmap(imageService.getImage(blog.getPic())); picIV.setOnClickListener(new OnClickListener() {//创建一个匿名内部类 public void onClick(View v) { Intent intent=new Intent();//注册一个意图 intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(blog.getPic()));//解析一个地址 startActivity(intent); } }); } catch (Exception e) { e.printStackTrace(); } return view; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public int getCount() { // TODO Auto-generated method stub return blogs.size();//这个要返回一个blogs的长度 } }; }
5.
imageService
package cn.itcast.blog; import java.io.File; import java.io.FileOutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import android.accounts.NetworkErrorException; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; public class ImageService { private Context context; // 创造它的构造函数 public ImageService(Context context) { this.context = context; } // 写一个获取图片的方法 public Bitmap getImage(String address) throws Exception { // 1.判断是否有图片的资源,如果没有的话直接返回空 if (address == null) return null; // 2、获得地址,然后打开连接 URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 获得连接对象 // ,然后打开连接 conn.setConnectTimeout(3000);// 设置超时时间 // 8、缓存文件 File cacheFile = new File(context.getCacheDir(), URLEncoder.encode(address));// 缓存文件 if (cacheFile.exists())// 9、判断是否有缓存文件存在 conn.setIfModifiedSince(cacheFile.lastModified());// 10、发送缓存文件的最后修改时间 // 3、获得状态码,判断是否为缓存文件 int code = conn.getResponseCode();// 获得状态码 if (code == 200) { // 4.如果请求成功,那么就开始读取网路数据 byte[] data = Util.read(conn.getInputStream()); // 5、使用BitmapFactory方法把读取到的字符转化为图片 Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length); writeCache(cacheFile, bm); // 6、开启新线程,写出图片到本地。 return bm; } else if (code == 304) { // 7、读取本地数据,转化为图片 return BitmapFactory.decodeFile(cacheFile.getAbsolutePath()); } throw new NetworkErrorException("访问服务器出错:" + code); } // 开启新线程来写图片缓存 private void writeCache(final File cacheFile, final Bitmap bm) { // 开启新线程 new Thread() { public void run() { try { FileOutputStream fos = new FileOutputStream(cacheFile); bm.compress(CompressFormat.JPEG, 100, fos);// 转存到本地 fos.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } }; }.start(); } }
6.blogService
package cn.itcast.blog; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import android.accounts.NetworkErrorException; import android.util.Xml; public class BlogService { public List<Blog> getBlogs() throws Exception{//业务类把错误抛出去 URL url=new URL("http://192.168.1.126/Myweb/blogs.xml"); //1、指定服务端地址 HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //2、打开连接对象 conn.setConnectTimeout(3000);//设置超时时间为3秒 3、设置超时时间 //下一步开始判断返回值 int code=conn.getResponseCode(); //4、从服务端读取数据,解析xml if(code==200){ //创建一个方法,通过输入流来解析xml return parseBlog(conn.getInputStream()); } throw new NetworkErrorException("连接失败:"+code); } //解析xml对象 private List<Blog> parseBlog(InputStream inputStream) throws Exception { // TODO Auto-generated method stub XmlPullParser parser=Xml.newPullParser(); parser.setInput(inputStream, "UTF-8"); List<Blog> blogs=new ArrayList<Blog>(); Blog blog=null; //解析xml文件 for(int type=parser.getEventType();type!=XmlPullParser.END_DOCUMENT;type=parser.next()){ //解析 if(type==XmlPullParser.START_TAG){ if("blog".equals(parser.getName())){ blog=new Blog();//如果是它我就创建对象,然后放进去 blogs.add(blog); }else if("portrait".equals(parser.getName())){ blog.setPortrait(parser.nextText()); }else if("name".equals(parser.getName())){ blog.setName(parser.nextText()); }else if("content".equals(parser.getName())){ blog.setContent(parser.nextText()); }else if("pic".equals(parser.getName())){ blog.setPic(parser.nextText()); }else if("from".equals(parser.getName())){ blog.setFrom(parser.nextText()); } } } return blogs;//如果xml里面什么都没有 ,那么就返回blog } }
7.util
package cn.itcast.blog; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class Util { public static byte[] read(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) baos.write(buffer, 0, len); baos.close(); byte[] data = baos.toByteArray(); return data; } }
8.附件:服务器上的xml解析文件
<?xml version="1.0" encoding="UTF-8"?> <blogs> <blog> <portrait>http://192.168.1.126/Myweb/b1.jpg</portrait> <name>QQ音乐</name> <content>问自己一个问题:既然1+2=2+1,那么是否 I love you=you love me?</content> <pic>http://192.168.1.126/Myweb/b2.jpg</pic> <from>来自 QQ空间说说</from> </blog> <blog> <portrait>http://192.168.1.126/Myweb/portrait2.jpeg</portrait> <name>江南小丑</name> <content>为什么总感觉还会再见到你? 既然走了为什么再回来? </content> <from>来自 QQ空间说说</from> </blog> <blog> <portrait>http://192.168.1.126/Myweb/portrait3.jpeg</portrait> <name>美食广场</name> <content>好诱人的美食哦,你要不要尝尝?</content> <pic>http://192.168.1.126/Myweb/content1.jpeg</pic> <from>来自 腾讯微博</from> </blog> <blog> <portrait>http://192.168.1.126/Myweb/portrait1.jpeg</portrait> <name>蒋坤</name> <content>好像双系统不那么好Ghost啊!</content> <from>来自 QQ空间说说</from> </blog> <blog> <portrait>http://192.168.1.126/Myweb/portrait2.jpeg</portrait> <name>蔓珠莎华</name> <content>为什么总感觉还会再见到你? 既然走了为什么再回来? </content> <from>来自 QQ空间说说</from> </blog> <blog> <portrait>http://192.168.1.126/Myweb/portrait3.jpeg</portrait> <name>各种诱惑美食</name> <content>宫廷桂花糕, 好正点!!</content> <pic>http://192.168.1.126/Myweb/content1.jpeg</pic> <from>来自 腾讯微博</from> </blog> </blogs>