zoukankan      html  css  js  c++  java
  • 安卓开发_浅谈ListView之分页列表

    前言:

    在开发的过程中,有时候我们需要从网络解析一些数据,比如最近的一些新闻,我们需要把这些数据用ListView显示出来。

    因为是解析一个网络数据源,这样将会一下子将所有的数据解析出来,当数据源数据过大时,就可能会造成解析时间过长,占用内存过大等问题。

    这时候想到用分页列表来显示这些数据,即每次只显示一个屏幕所能容纳条数的列表项数据,当用户手指向下拉动的时候,才再加载一个屏幕所能容纳的条数的数据,这样就解决了上述问题。

    ---------------------------------------------------------------------------------------------------------------------------------

    思路:

    先来看一个数据源地址,内容为某一个城市待出售房屋信息

    1 http://ikft.house.qq.com/index.php?guid=866500021200250&devua=appkft_1080_1920_XiaomiMI4LTE_1.8.3_Android19&order=0&searchtype=normal&devid=866500021200250&appname=QQHouse&mod=appkft&act=searchhouse&channel=71&page=1&rn=20&cityid=1

    该地址红色部分代表页数,rn=20代表一页有20条相应数据

    通过www.bejson.com网站解析该网址相应的JSON数据为XML格式

     1 {
     2     "retcode": 0,
     3     "retmsg": "成功",
     4     "total": "817",
     5     "page": 1,
     6     "rn": 20,
     7     "data": [
     8         {
     9             "fid": "122591",
    10             "fcover": "http://p0.qpic.cn/estate/0/cbcef0b36d585650ec602ebe0ca56a18.jpg/180",
    11             "fname": "鸿坤·理想湾",
    12             "faddress": "涿州东高铁新城涿州东站西侧300米",
    13             "fregion": "大北京",
    14             "fpricedisplaystr": "7200元/平米",
    15             "faroundhighprice": 7500,
    16             "faroundlowprice": 6500,
    17             "groupbuynum": 3587,
    18             "lng": "116.052084096376",
    19             "lat": "39.4636526249295",
    20             "fsellstatus": "1",
    21             "istencentdiscount": 0,
    22             "bookmark": [
    23                 {
    24                     "tag": "看房团",
    25                     "type": 2
    26                 },
    27                 {
    28                     "tag": "低总价",
    29                     "type": 3
    30                 },
    31                 {
    32                     "tag": "品牌开发商",
    33                     "type": 3
    34                 }
    35             ],
    36             "price_pre": "均价",
    37             "price_value": "7200",
    38             "price_unit": "元/平米",
    39             "panoid": "",
    40             "heading": "",
    41             "pitch": "",
    42             "has_agent": 1,
    43             "hui": 1
    44         },
    45        

    也就是说,当我们解析这个网址的数据时,会有20条数据,当把网址红色部分page=1 --->page=2 时,又将显示20条数据

    怎么实现分页列表一次显示20条数据呢?

    从数据源网址可以看出一个我们只要把page依次加一,便可以依次加载对应网址数据源了

    也就是说,只要把每次加载的数据添加到适配器中,便可以实现分页列表每页每次加载固定个数个数据条

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    代码:

    1、解析房屋信息,我们这里先只获得房屋名字信息放到ListView中

    先建一个房屋实体类

     1 package com.example.listview;
     2 
     3 public class Home {
     4         private String name;
     5 
     6         public Home() {
     7             super();
     8             // TODO Auto-generated constructor stub
     9         }
    10 
    11         public Home(String name) {
    12             super();
    13             this.name = name;
    14         }
    15 
    16         public String getName() {
    17             return name;
    18         }
    19 
    20         public void setName(String name) {
    21             this.name = name;
    22         }
    23 
    24         @Override
    25         public String toString() {
    26             return name;
    27         }
    28         
    29 }
    Home.class

    2、工具类(http获取数据,json数据解析)

     1 package com.example.listview;
     2 
     3 import java.io.ByteArrayOutputStream;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 import java.net.HttpURLConnection;
     7 import java.net.MalformedURLException;
     8 import java.net.URL;
     9 
    10 public class HttpUtil {
    11     //将指定路径上的数据转换为字节数组形式返回
    12     public static byte[] getByteJsonString(String path) throws IOException
    13     {
    14         URL url = new URL(path);
    15         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    16         conn.setRequestMethod("GET"); //Get的连接方式
    17         conn.setConnectTimeout(5000);
    18         conn.setDoInput(true);
    19         if(conn.getResponseCode()==200)// 响应码等于200表示连接成功
    20         {
    21             InputStream in = conn.getInputStream();
    22             return getByteString(in);
    23         }
    24         return null;
    25         
    26     }
    27     
    28     public static byte[] getByteString(InputStream in) throws IOException
    29     {
    30         //内存流获取数据
    31         ByteArrayOutputStream out = new ByteArrayOutputStream();
    32         int len = 0;
    33         byte[] b = new byte[1024];
    34         while((len = in.read(b))!=-1)
    35         {
    36             //注意不要写成out.write(b);  否则若字节数据长度大于实际数据长度,后面部分乱码,导致后面json解析出错
    37             out.write(b,0,len);
    38         }
    39         
    40         return out.toByteArray();
    41     }
    42     
    43 }
    HttpUtil.class
     1 package com.example.listview;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import org.json.JSONArray;
     7 import org.json.JSONException;
     8 import org.json.JSONObject;
     9 
    10 
    11 public class JsonString {
    12     public static List getJsonResult(String json) throws JSONException
    13     {
    14         //JSON解析 ,解析某一城市下所有房屋的名字
    15         List<Home> list = new ArrayList<Home>();
    16         JSONObject obj = new JSONObject(json);
    17         JSONArray arr = obj.getJSONArray("data");
    18         Home home = null;
    19         for(int i=0;i<arr.length();i++)
    20         {
    21             
    22             JSONObject data = arr.getJSONObject(i);
    23             home = new Home();
    24             
    25         
    26             String fname =data.getString("fname");
    27             home.setName(fname);
    28             list.add(home);
    29         }
    30         return list;
    31         
    32         
    33     }
    34 }
    JsonString.class解析JSON数据

    3、ListView的自定义适配器类

     1 package com.example.listview;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import android.content.Context;
     7 import android.view.LayoutInflater;
     8 import android.view.View;
     9 import android.view.ViewGroup;
    10 import android.widget.BaseAdapter;
    11 import android.widget.TextView;
    12 
    13 public class MyAdapter extends BaseAdapter{
    14 
    15     private Context context;
    16     private List<Home> list;
    17     
    18     public MyAdapter(Context context)
    19     {
    20         this.context = context;
    21         list = new ArrayList<Home>();
    22     }
    23     //关键点!
    24     //将底部下拉刷新出来的数据(新解析出来的固定条数数据)添加到当前适配器中
    25     public void addData(List lists){
    26         list.addAll(lists);
    27     }
    28     @Override
    29     public int getCount() {
    30         // TODO Auto-generated method stub
    31         int count = 0;
    32         if(list!=null)
    33             return list.size();
    34         return count;
    35     }
    36 
    37     @Override
    38     public Object getItem(int position) {
    39         // TODO Auto-generated method stub
    40         return list.get(position);
    41     }
    42 
    43     @Override
    44     public long getItemId(int position) {
    45         // TODO Auto-generated method stub
    46         return position;
    47     }
    48 
    49     @Override
    50     public View getView(int position, View convertView, ViewGroup parent) {
    51         // TODO Auto-generated method stub
    52         View view = null;
    53         if(convertView!=null)
    54         {
    55             view = convertView;
    56         }
    57         else 
    58         {
    59             view = LayoutInflater.from(context).inflate(R.layout.layout_item,parent, false);
    60         }
    61         
    62         ViewHolder holder = (ViewHolder) view.getTag();
    63         if(holder==null)
    64         {
    65             holder = new ViewHolder();
    66             holder.textview = (TextView) view.findViewById(R.id.id_textview);
    67             view.setTag(holder);
    68         }
    69         holder.textview.setText(list.get(position).getName());
    70         return view;
    71     }
    72     
    73     class ViewHolder 
    74     {
    75         TextView textview;
    76     }
    77 
    78 }
    MyAdapter.class

    4、异步任务获得数据

     1 package com.example.listview;
     2 
     3 import java.io.IOException;
     4 import java.io.UnsupportedEncodingException;
     5 import java.util.ArrayList;
     6 import java.util.List;
     7 
     8 import org.json.JSONException;
     9 
    10 import android.os.AsyncTask;
    11 
    12 public class AsyncTaskHome extends AsyncTask<String, Void, List>{
    13 
    14     private MyAdapter myadapter;
    15     private List<Home> list ;
    16     //将适配器作为参数传进来
    17     public AsyncTaskHome(MyAdapter myadapter)
    18     {
    19         this.myadapter = myadapter;
    20     }
    21     @Override
    22     protected List doInBackground(String... params) {
    23         // TODO Auto-generated method stub
    24         if(params[0]!=null)
    25         {
    26             try {
    27                 String json = new String(HttpUtil.getByteJsonString(params[0]),"utf-8");
    28                 list = JsonString.getJsonResult(json);
    29             } catch (UnsupportedEncodingException e) {
    30                 // TODO Auto-generated catch block
    31                 e.printStackTrace();
    32             } catch (IOException e) {
    33                 // TODO Auto-generated catch block
    34                 e.printStackTrace();
    35             } catch (JSONException e) {
    36                 // TODO Auto-generated catch block
    37                 e.printStackTrace();
    38             }
    39         }
    40         
    41         return list;
    42     }
    43     
    44     @Override
    45     protected void onPostExecute(List result) {
    46         // TODO Auto-generated method stub
    47         super.onPostExecute(result);
    48         //将解析除的数据添加放入到当前适配器中
    49         myadapter.addData(result);
    50         //刷新适配器
    51         myadapter.notifyDataSetChanged();
    52         
    53         
    54     }
    55     
    56 }
    AsyncTaskHome.class

    5、主Activity

     1 package com.example.listview;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 import android.widget.AbsListView;
     6 import android.widget.AbsListView.OnScrollListener;
     7 import android.widget.ListView;
     8 import android.widget.Toast;
     9 
    10 public class MainActivity extends Activity {
    11     
    12     private ListView listview ;
    13     private boolean isEnd; //判断列表是否滑动到底部
    14     private int page = 1;//显示第几页数据
    15     @Override
    16     protected void onCreate(Bundle savedInstanceState) {
    17         super.onCreate(savedInstanceState);
    18         setContentView(R.layout.activity_main);
    19     
    20         listview = (ListView) findViewById(R.id.listview);
    21         //创建一个自定义适配器对象
    22         final MyAdapter adapter = new MyAdapter(this);
    23         //将该适配器作为listView的数据源
    24         listview.setAdapter(adapter);
    25         //启动异步任务,先解析第一个页面的数据
    26         new AsyncTaskHome(adapter).execute("http://ikft.house.qq.com/index.php?guid=866500021200250&devua=appkft_1080_1920_XiaomiMI4LTE_1.8.3_Android19&order=0&searchtype=normal&devid=866500021200250&appname=QQHouse&mod=appkft&act=searchhouse&channel=71&page=1&rn=20&cityid=1");
    27 
    28         listview.setOnScrollListener(new OnScrollListener() {
    29             
    30             @Override
    31             public void onScrollStateChanged(AbsListView view, int scrollState) {
    32                 // TODO Auto-generated method stub
    33                 //如果滑動到末尾並且手指離開了界面,則加載新的數據源添加到適配器中
    34                 if(isEnd && scrollState==OnScrollListener.SCROLL_STATE_IDLE)
    35                 {
    36                     Toast.makeText(MainActivity.this, "努力加载中---", 1).show();
    37                 
    38                     //加载一个新的数据源,包含新的20条数据
    39                     String path = "http://ikft.house.qq.com/index.php?guid=866500021200250&devua=appkft_1080_1920_XiaomiMI4LTE_1.8.3_Android19&order=0&searchtype=normal&devid=866500021200250&appname=QQHouse&mod=appkft&act=searchhouse&channel=71&page="+(++page)+"&rn=20&cityid=1";
    40                     //执行异步任务,将当前的自定义适配器传进去,将解析的新的数据添加到当前视频日期中
    41                     new AsyncTaskHome(adapter).execute(path);
    42                 }
    43             }
    44             @Override
    45             public void onScroll(AbsListView view, int firstVisibleItem,
    46                     int visibleItemCount, int totalItemCount) {
    47                 // TODO Auto-generated method stub
    48                 //如果已经划出去的列表项和正在显示的列表项==全部列表项,说明列表到达底部
    49                 isEnd = (firstVisibleItem+visibleItemCount)==totalItemCount;
    50             }
    51         });
    52     
    53     
    54     }
    55 
    56     
    57 
    58 }
    MainActivity.class

    效果图:

  • 相关阅读:
    Dos命令大全(收藏)
    asp.net读写Cookies
    asp.net文件下载
    使用存储过程分页
    (十)死锁检测算法
    poj1664
    一席话惊醒梦中人
    深入了解scanf()/getchar()和gets()/cin等函数
    小结《malloc与new之区别》
    (六)文件管理
  • 原文地址:https://www.cnblogs.com/xqxacm/p/4787537.html
Copyright © 2011-2022 走看看