首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓开发_浅谈ListView之分页列表

安卓开发_浅谈ListView之分页列表

作者头像
听着music睡
发布2018-05-18 13:04:50
1K0
发布2018-05-18 13:04:50
举报
文章被收录于专栏:Android干货Android干货

前言:

在开发的过程中,有时候我们需要从网络解析一些数据,比如最近的一些新闻,我们需要把这些数据用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 }

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 }
 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 }

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 }

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 }

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 }

效果图:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-09-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档