模拟网易新闻
根据黑马Android28期视频做的东西,小程序涉及到了BaseAdapter,HttpClient,XmlPullParser,Handler第一次写博客这玩意。。。还真不知道入手点。。黑马28期视频也看了6天的了(耗时2周了吧。。),总算完成了一个相对而言有点价值的玩意。。。。这个模拟网易新闻的玩意,主界面用的ListView,每个新闻信息,使用RelativeLayout布局,无非就是几张图片,几个文本,给出的样本XML文件解析起来方便的多,因为是人为优化过的。。。(后来自己从网易新闻找到XML解析。。。)开始整理一个新闻类(包括标题啊,描述啊,图片啊。。之类的(模拟最恶心的就是那个跟帖= =!))首先从XML文件得到输入流ispublic ListgetNewsFromInternet() { HttpClient client = null; try { client = new DefaultHttpClient(); HttpGet get = new HttpGet( "http://192.168.1.102:8080/NetEaseServer/new.xml");//解析地址 HttpResponse response = client.execute(get); int statusCode = response.getStatusLine().getStatusCode();//返回状态码,200就是成功 if (statusCode == 200) { InputStream is = response.getEntity().getContent();//通过这玩意得到流,然后就可以得到文本(新闻) List newsinfo = getNewsFromInputStream(is); return newsinfo; } else { Log.i(TAG, "访问失败: " + statusCode); } } catch (Exception e) { e.printStackTrace(); } finally { if (client != null) { client.getConnectionManager().shutdown();//关闭HttpClient } } return null; }
然后从流解析出文本
public ListgetNewsFromInputStream(InputStream is) throws Exception { XmlPullParser parser = Xml.newPullParser(); parser.setInput(is, "utf-8");//不想出乱码,就得改编码。。 int eventTypy = parser.getEventType();//解析标签的类型,0是START_DOCUMENT,1是END_DOCUMENT ,2是 START_TAG ,3是END_TAG List newInfoList = null; NewsInfo info = null; while (eventTypy != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName();// 总要获得一下节点名称,毕竟StartTag是<>,EndTag是 switch (eventTypy) { case XmlPullParser.START_TAG: if ("news".equals(tagName)) {//匹配最大的节点,创建集合 newInfoList = new ArrayList (); } else if ("new".equals(tagName)) {//匹配每条节点,创建新闻,后面就是内容了 info = new NewsInfo(); } else if ("title".equals(tagName)) { info.setTitle(parser.nextText()); } else if ("detail".equals(tagName)) { info.setDetail(parser.nextText()); } else if ("comment".equals(tagName)) {//最2B的跟帖评论量。。。。 info.setComment(parser.nextText()); } else if ("image".equals(tagName)) { info.setImage(parser.nextText()); } break; case XmlPullParser.END_TAG: if ("new".equals(tagName)) { newInfoList.add(info); } break; } eventTypy = parser.next(); } return newInfoList; }
初始化方法开启线程,由于子线程无法直接改写View,所以通过Message向Handler对象传送数据
public void init() { listview = (ListView) findViewById(R.id.lv_list); new Thread(new Runnable() {//第一次用这种方式开启线程 @Override public void run() { ListlistInfo = getNewsFromInternet();//获得集合 Message msg = new Message();//创建消息对象 if (listInfo != null) { msg.what = 1;//好吧,我犯懒了,这个是成功的标志位(按理说应该弄个SUCCESS常量的。。。) msg.obj = listInfo;//成功发送新闻集合 } else { msg.what = 0;//失败标志位 } handler.sendMessage(msg);//我开始就是这里犯二了。。。竟然没发送消息- -怪不得模拟器上面是空孔的。。。 } }).start();//线程开启,没啥说的 }
关于Handler对象
private Handler handler = new Handler() { @Override public void handleMessage(android.os.Message msg) {//重写接收消息的方法 switch (msg.what) {//根据标志位判断操作 case 1: newsInfoList=(List) msg.obj;//对象强转一下就可以了。。 MyAdapter adapter = new MyAdapter();//后面的内部类,每条消息的内容设置。。。 listview.setAdapter(adapter);//这个- -我开始又忘了加了。。不设置Adapter,列表怎么会显示嘛= =~~~~ break; case 0: Toast.makeText(MainActivity.this, "当前网络崩溃了.", 0).show();//失败消息 break; } } };
内部类MyAdapter
class MyAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return newsInfoList.size();//返回一共有多少条信息 } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view =null; if(convertView!=null){ view =convertView;//这玩意貌似是缓存对象吧,具体咋回事我也不太明白。。还得在研究一下 }else{ LayoutInflater inflater =getLayoutInflater(); //着两行就完全不明白了= =啥东西。。。按照教程写的。。。 view=inflater.inflate(R.layout.list_item, null); } SmartImageView siv_icon = (SmartImageView) view.findViewById(R.id.siv_icon);//忘了说了。。这个是从Github上面找的一个Android开源框架的玩意。。。就是设置图片的。。。还挺好用的。。 TextView tv_comment = (TextView) view.findViewById(R.id.tv_comment); TextView tv_detail = (TextView) view.findViewById(R.id.tv_detail); TextView tv_title = (TextView) view.findViewById(R.id.tv_title); NewsInfo news =newsInfoList.get(position); siv_icon.setImageUrl(news.getImage());//这个简单了。。直接给地址就能出图片- -省了好多麻烦。。。 tv_detail.setText(news.getDetail()); tv_comment.setText(news.getComment()+"跟帖"); tv_title.setText(news.getTitle()); return view;//中间这里一直返回null。。。。害我查了半天= =下次这种错误不能犯!!! } }
基本核心内容就是上面这些,但是这些只能解析- -他给的文档。。。。
好吧,接下来自己动手稍微改了一下。。。。
public ListgetNewsFromInputStream(InputStream is) throws Exception { XmlPullParser parser = Xml.newPullParser(); parser.setInput(is, "utf-8"); int eventTypy = parser.getEventType(); List newInfoList = null; NewsInfo info = null; while (eventTypy != XmlPullParser.END_DOCUMENT) { Log.i(TAG, eventTypy+""); String tagName = parser.getName();// 节点名称 switch (eventTypy) { case XmlPullParser.START_TAG: if ("channel".equals(tagName)) { newInfoList = new ArrayList (); } else if ("item".equals(tagName)) { info = new NewsInfo(); } else if ("title".equals(tagName)&&info!=null) {/*对于网易新闻。。。。比较坑的是。。。他会加 网易新闻 这个标签。。。 还不是在- 之间,开始运行不通过,就是因为这里info还是null,所以直接空指针异常了*/ info.setTitle(parser.nextText()); } else if ("description".equals(tagName)&&info!=null) { String str=parser.nextText(); info.setDetail(str.substring(0, str.indexOf("......")));//这里是实属无奈= =里面竟然出现了HTML代码。。。我只好先把HTML部分截掉了。。。。。。。。。。。。 } break; case XmlPullParser.END_TAG: if ("item".equals(tagName)) { newInfoList.add(info); } break; default: break; } eventTypy = parser.next(); } return newInfoList; }
-0-这玩意就能接收网易新闻XML文件了。。。
不过还有一点比较蛋疼。。。这个描述里面还有HTML的玩意。。这个玩意咋处理呢。。。(我这里直接截掉了- -~~)