模拟网易新闻

模拟网易新闻


根据黑马Android28期视频做的东西,小程序涉及到了BaseAdapter,HttpClient,XmlPullParser,Handler

第一次写博客这玩意。。。还真不知道入手点。。

黑马28期视频也看了6天的了(耗时2周了吧。。),总算完成了一个相对而言有点价值的玩意。。。。

这个模拟网易新闻的玩意,主界面用的ListView,每个新闻信息,使用RelativeLayout布局,无非就是几张图片,几个文本,给出的样本XML文件解析起来方便的多,因为是人为优化过的。。。(后来自己从网易新闻找到XML解析。。。)

开始整理一个新闻类(包括标题啊,描述啊,图片啊。。之类的(模拟最恶心的就是那个跟帖= =!))

首先从XML文件得到输入流is

public List<NewsInfo> getNewsFromInternet() {
        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> 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 List<NewsInfo> getNewsFromInputStream(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<NewsInfo> 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<NewsInfo>();
                } 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() {
                List<NewsInfo> listInfo = 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<NewsInfo>) 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 List<NewsInfo> getNewsFromInputStream(InputStream is)
            throws Exception {
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(is, "utf-8");
        int eventTypy = parser.getEventType();
        
        List<NewsInfo> 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<NewsInfo>();
                } else if ("item".equals(tagName)) {
                    info = new NewsInfo();
                } else if ("title".equals(tagName)&&info!=null) {/*对于网易新闻。。。。比较坑的是。。。他会加<title>网易新闻</title>这个标签。。。
                                                                  还不是在<item></item>之间,开始运行不通过,就是因为这里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的玩意。。这个玩意咋处理呢。。。(我这里直接截掉了- -~~)

你可能感兴趣的:(httpclient,android,BaseAdapter,handler,xmlpullparser)