从网络读取数据并动态的显示在ListView中

2017/6/9 12:40:07 人评论 次浏览 分类:ListView

 

这两天写了个小程序,使用了从网络读取xml数据,并显示在ListView中。

这里面有几个关键点:

从网络读取数据

SAX解析xml

异步填充ListView

先看下截图:

 

\

 

非常简单的界面哈

 

为了方便,我再自己的服务器上,放了一个xml文件,其内容主要是:

 

<?xml version="1.0"?> 

<products> 

    <product> 

        <price>100</price> 

        <name>android dev</name> 

        <image src="image/android1.png"/> 

    </product> 

    <product> 

        <price>100</price> 

        <name>androiddev2</name> 

        <image src="image/android1.png"/> 

    </product> 

<!-- 接着重复下去.... --> 

</products> 

 

该程序,首先用一个AsyncTask新启一个线程,来下载和解析xml;和主线程通过Handler对象来通讯。

 

 

 

下载XML文件

 

通过HTTPGet来下载xml。这时apache提供的包,需要首先包含如下包:

 

 

import org.apache.http.HttpEntity; 

import org.apache.http.HttpResponse; 

import org.apache.http.HttpStatus; 

import org.apache.http.client.HttpClient; 

import org.apache.http.client.methods.HttpGet; 

import org.apache.http.impl.client.DefaultHttpClient; 

 

代码如下:(使用Get方法)

 

protected String doInBackground(String... params) { 

    HttpGet httpRequest = new HttpGet(params[0]); //从url 创建一个HttpGet对象 

    HttpClient httpclient = new DefaultHttpClient(); 

     

    //mShowHtml.setText(""); 

    try { 

        HttpResponse httpResponse = httpclient.execute(httpRequest); 

          

        if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//获取http的返回值代码 

            HttpEntity entitiy = httpResponse.getEntity(); 

             

            InputStream in = entitiy.getContent();//获得内容 

            //解析xml,下面详述 

            InputSource source = new InputSource(in); 

             

            SAXParserFactory sax = SAXParserFactory.newInstance(); 

            XMLReader xmlReader = sax.newSAXParser().getXMLReader(); 

             

            xmlReader.setContentHandler(new ProductHandler()); 

             

            xmlReader.parse(source); 

             

        } 

        else { 

            //return "请求失败!"; 

            //mShowHtml.setText("请求失败"); 

            //Message mymsg = mMainHandler.obtainMessage(); 

            //mymsg.obj = "请求失败"; 

            //mMainHandler.sendMessage(mymsg); 

        } 

     

    }catch(IOException e){ 

        e.printStackTrace(); 

    }catch(SAXException e) { 

        e.printStackTrace(); 

    }catch(ParserConfigurationException e) { 

        e.printStackTrace(); 

    } 

    return null; 

 

 

解析XML

使用SAX的解析方法,先包含必须得包

 

import org.xml.sax.InputSource; 

import org.xml.sax.SAXException; 

import org.xml.sax.XMLReader; 

import org.xml.sax.helpers.DefaultHandler; 

 

解析的代码,正如上面所示:

 

                

//InputSource是解析源,可以通过一个InputStream创建 

urce source = new InputSource(in);                   

SAXParserFactory sax = SAXParserFactory.newInstance(); 

der xmlReader = sax.newSAXParser().getXMLReader();                            

xmlReader.setContentHandler(new ProductHandler());//ProductHandler是解析的句柄                         

der.parse(source); 

SAX主要使用ContentHandler接口来传递解析好得数据,不过,更经常使用的是DefaultHandler

 

 

class ProductHandler extends DefaultHandler { //从DefaultHandler继承即可 

    private ProductInfo curProduct; 

    private String content; 

    //解析到一个标签时调用 

    public void startElement(String uri, String localName, String name, org.xml.sax.Attributes attributes) throws SAXException { 

        if(localName.equals("product")) {//遇到product标签,进行解析 

            curProduct = new ProductInfo(); 

        } 

        else if(localName.equals("image")) { 

            //set name 

            curProduct.image = attributes.getValue("src");//提取image src属性 

        } 

        super.startElement(uri, localName, name, attributes); 

    } 

     

    public void endElement(String uri, String localName, String name) throws SAXException{ 

        if(localName.equals("product")) {//当解析到一个标签结束时,发送一个消息,把Product类作为参数传递 

            //send event 

            //get main handler 

            Message msg = mMainHandler.obtainMessage(); 

            msg.obj = curProduct; 

            mMainHandler.sendMessage(msg); 

            //Log.i("Product:", curProduct.toString()); 

        } 

        else if(localName.equals("name")) { 

            //set name 

            curProduct.name = content;//保存名字 

        } 

        else if(localName.equals("price")) { 

            curProduct.price = Float.parseFloat(content);<span style="background-color: rgb(255, 255, 255); ">//保存价格</span> 

 

        } 

        super.endElement(uri, localName, name); 

    } 

    //这里获取具体的内容,是标签下保存的文本 

    public void characters (char[] ch, int start, int length)  throws SAXException 

    { 

        content = new String(ch, start, length); 

        //Log.i("Parser:" ,content); 

        super.characters(ch, start, length); 

    } 

 

ProductInfo类的定义非常简单

 

class ProductInfo { 

    public String name; 

    public float price; 

    public String image; 

    public String toString() { 

        return "\nName:" + name +"\nPrice :" + price + "\nImage:" + image; 

    } 

 

在AsyncTask中执行以上代码

 

public class GetHttpTask extends AsyncTask<String, Integer, String> { 

 

    public GetHttpTask() { 

    } 

     

    protected void onPreExecute() { //在进入线程之前执行。该函数在调用者线程内执行 

         

    } 

     

    protected String doInBackground(String... params) {//线程的执行主体 

        HttpGet httpRequest = new HttpGet(params[0]); 

.................. //主要执行下载和解析的嗲吗 

        return null; 

    } 

     

    protected void onPostExecute(String result) {//完成后调用 

         

    } 

在主线程中,调用GetHttpTask的execute方法就可以执行

 

      btn.setOnClickListener(new View.OnClickListener() {//在onCreate函数中调用 

     

    @Override 

    public void onClick(View v) { 

        // TODO Auto-generated method stub 

        httpGet(); 

    } 

}); 

httpGet方法:

 

void httpGet() { 

    GetHttpTask task = new GetHttpTask(); 

    task.execute("http://192.168.1.111:8080/nfcdemo/products.xml"); 

 } 

  

 

 

 

 

 

 

异步传递消息

上面的例子中,在endElement函数中,发送了消息,下面是接收消息

在主Activity中,声明了一个Handler mHandler对象,并在onCreate时,这样做

 

mMainHandler = new Handler() { 

    public  void handleMessage(Message msg) { 

        //mShowHtml.append((String)msg.obj); 

        if(msg.obj != null) { 

            ProductInfo prod = (ProductInfo)msg.obj; 

            Log.i("Prodcut:", prod.toString()); 

            //mShowHtml.append(prod.toString()); 

            HashMap<String, Object> map = new HashMap<String, Object>(); 

            map.put("name", prod.name); 

            map.put("price", "RMB" + prod.price); 

            mlist.add(map); //mlist保存了列表的具体数据 

            mProdList.notifyDataSetChanged();//mProdList是一个ListView对象,该函数引起ListView重读数据 

        } 

    } 

}; 

 

这个过程的要点基本如上,贴上所有代码吧!关于ListView的用法,可以参考http://blog.csdn.net/hellogv/article/details/4542668

 

主代码:

 

package com.test.http; 

 

import java.io.IOException; 

import java.io.InputStream; 

import java.util.ArrayList; 

import java.util.HashMap; 

 

import javax.xml.parsers.ParserConfigurationException; 

import javax.xml.parsers.SAXParserFactory; 

 

import org.apache.http.HttpEntity; 

import org.apache.http.HttpResponse; 

import org.apache.http.HttpStatus; 

import org.apache.http.client.HttpClient; 

import org.apache.http.client.methods.HttpGet; 

import org.apache.http.impl.client.DefaultHttpClient; 

import org.xml.sax.InputSource; 

import org.xml.sax.SAXException; 

import org.xml.sax.XMLReader; 

import org.xml.sax.helpers.DefaultHandler; 

 

import android.app.Activity; 

import android.os.AsyncTask; 

import android.os.Bundle; 

import android.os.Handler; 

import android.os.Message; 

import android.util.Log; 

import android.view.View; 

import android.widget.Button; 

import android.widget.EditText; 

import android.widget.ListView; 

import android.widget.SimpleAdapter; 

 

public class HtmltestActivity extends Activity { 

    EditText mUrlText; 

    //EditText mShowHtml; 

    ListView mProducts; 

    Handler mMainHandler; 

    SimpleAdapter mProdList; 

    ArrayList<HashMap<String,Object>> mlist; 

    /** Called when the activity is first created. */ 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

         

        mUrlText = (EditText)findViewById(R.id.eturl); 

        //mShowHtml = (EditText)findViewById(R.id.etshowhtml); 

        mProducts = (ListView)findViewById(R.id.productList); 

         

        Button btn = (Button)findViewById(R.id.btngo); 

         

         

        mlist = new ArrayList<HashMap<String, Object>>(); 

        mProdList = new SimpleAdapter(this, 

                mlist, 

                R.layout.listitem, 

                new String[]{"name", "price"}, 

                new int[]{R.id.prd_title, R.id.prd_price} 

                ); 

         

        mProducts.setAdapter(mProdList); 

         

         

        btn.setOnClickListener(new View.OnClickListener() { 

             

            @Override 

            public void onClick(View v) { 

                // TODO Auto-generated method stub 

                httpGet(); 

            } 

        }); 

         

        mMainHandler = new Handler() { 

            public  void handleMessage(Message msg) { 

                //mShowHtml.append((String)msg.obj); 

                if(msg.obj != null) { 

                    ProductInfo prod = (ProductInfo)msg.obj; 

                    Log.i("Prodcut:", prod.toString()); 

                    //mShowHtml.append(prod.toString()); 

                    HashMap<String, Object> map = new HashMap<String, Object>(); 

                    map.put("name", prod.name); 

                    map.put("price", "RMB" + prod.price); 

                    mlist.add(map); 

                    mProdList.notifyDataSetChanged(); 

                } 

            } 

        }; 

         

    } 

     

    void httpGet() { 

        GetHttpTask task = new GetHttpTask(); 

        task.execute("http://192.168.1.111:8080/nfcdemo/products.xml"); 

    } 

     

    public class GetHttpTask extends AsyncTask<String, Integer, String> { 

    

        public GetHttpTask() { 

        } 

         

        protected void onPreExecute() { 

             

        } 

         

        protected String doInBackground(String... params) { 

            HttpGet httpRequest = new HttpGet(params[0]); 

            HttpClient httpclient = new DefaultHttpClient(); 

             

            //mShowHtml.setText(""); 

            try { 

                HttpResponse httpResponse = httpclient.execute(httpRequest); 

                 

                if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ 

                    HttpEntity entitiy = httpResponse.getEntity(); 

                     

                    InputStream in = entitiy.getContent(); 

                     

                    InputSource source = new InputSource(in); 

                     

                    SAXParserFactory sax = SAXParserFactory.newInstance(); 

                    XMLReader xmlReader = sax.newSAXParser().getXMLReader(); 

                     

                    xmlReader.setContentHandler(new ProductHandler()); 

                     

                    xmlReader.parse(source); 

                      

                } 

                else { 

                    //return "请求失败!"; 

                    //mShowHtml.setText("请求失败"); 

                    //Message mymsg = mMainHandler.obtainMessage(); 

                    //mymsg.obj = "请求失败"; 

                    //mMainHandler.sendMessage(mymsg); 

                } 

             

            }catch(IOException e){ 

                e.printStackTrace(); 

            }catch(SAXException e) { 

                e.printStackTrace(); 

            }catch(ParserConfigurationException e) { 

                e.printStackTrace(); 

            } 

            return null; 

        } 

         

        protected void onPostExecute(String result) { 

            //mShowHtml.setText(result); 

        } 

    } 

     

    class ProductInfo { 

        public String name; 

        public float price; 

        public String image; 

        public String toString() { 

            return "\nName:" + name +"\nPrice :" + price + "\nImage:" + image; 

        } 

    } 

     

    class ProductHandler extends DefaultHandler { 

        private ProductInfo curProduct; 

        private String content; 

         

        public void startElement(String uri, String localName, String name, org.xml.sax.Attributes attributes) throws SAXException { 

            if(localName.equals("product")) { 

                curProduct = new ProductInfo(); 

            } 

            else if(localName.equals("image")) { 

                //set name 

                curProduct.image = attributes.getValue("src"); 

            } 

            super.startElement(uri, localName, name, attributes); 

        } 

         

        public void endElement(String uri, String localName, String name) throws SAXException{  

            if(localName.equals("product")) { 

                //send event 

                //get main handler 

                Message msg = mMainHandler.obtainMessage(); 

                msg.obj = curProduct; 

                mMainHandler.sendMessage(msg); 

                //Log.i("Product:", curProduct.toString()); 

            } 

            else if(localName.equals("name")) { 

                //set name 

                curProduct.name = content; 

            } 

            else if(localName.equals("price")) { 

                curProduct.price = Float.parseFloat(content); 

            } 

            super.endElement(uri, localName, name); 

        } 

         

        public void characters (char[] ch, int start, int length)  throws SAXException 

        { 

            content = new String(ch, start, length); 

            //Log.i("Parser:" ,content); 

            super.characters(ch, start, length); 

        } 

    } 

 

 

main.xml

 

<?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" > 

 

    <LinearLayout 

        android:id="@+id/linearLayout1" 

        android:layout_width="match_parent" 

        android:layout_height="wrap_content" > 

 

 

 

 

        <EditText 

            android:id="@+id/eturl" 

            android:layout_width="match_parent" 

            android:layout_height="wrap_content" 

            android:layout_weight="1" > 

 

            <requestFocus /> 

        </EditText> 

 

 

        <Button 

            android:id="@+id/btngo" 

            android:layout_width="100dp" 

            android:layout_height="wrap_content" 

            android:layout_weight="1" 

            android:text="Go!" /> 

 

    </LinearLayout> 

 

 

 

    <ListView 

        android:id="@+id/productList" 

        android:layout_width="match_parent" 

        android:layout_height="match_parent" > 

 

    </ListView> 

 

</LinearLayout> 

 

 

listitem.xml

 

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:layout_width="match_parent" 

    android:layout_height="match_parent" > 

 

 

    <ImageView 

        android:id="@+id/product_icon" 

        android:layout_width="wrap_content" 

        android:layout_height="wrap_content" 

        android:layout_alignParentLeft="true" 

        android:layout_alignParentTop="true" 

        android:src="@drawable/ic_launcher" /> 

 

    <TextView 

        android:id="@+id/prd_title" 

        android:layout_width="wrap_content" 

        android:layout_height="wrap_content" 

        android:layout_alignParentTop="true" 

        android:layout_toRightOf="@+id/product_icon" 

        android:text="TextView" /> 

 

 

    <TextView 

        android:id="@+id/prd_price" 

        android:layout_width="wrap_content" 

        android:layout_height="wrap_content" 

        android:layout_alignParentRight="true" 

        android:layout_alignParentTop="true" 

        android:text="TextView" /> 

 

</RelativeLayout>   

 

doon的专栏

分享到: 腾讯 新浪 人人网 邮件 收藏夹 复制网址 更多

上一篇:Android中ListView和ScrollView总结【安卓进化二十九】

下一篇:Android实战技巧:如何在ScrollView中嵌套ListView

相关教程


共有访客发表了评论 网友评论

验证码: 看不清楚?