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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 前言: 在开发的过程中,有时候我们需要从网络解析一些数据,比如最近的一些新闻,我们需要把这些数据用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

 

效果图:

 

相关文章
|
15天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
15天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14
|
18天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
16天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
29 5
|
14天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
16天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
15天前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
19天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
15天前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
24 0
|
18天前
|
存储 监控 Java
探索安卓开发:从基础到进阶的旅程
在这个数字时代,移动应用已成为我们日常生活的一部分。对于开发者来说,掌握安卓开发不仅是技能的提升,更是通往创新世界的钥匙。本文将带你了解安卓开发的核心概念,从搭建开发环境到实现复杂功能,逐步深入安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的见解和技巧,帮助你在安卓开发的道路上更进一步。
19 0