前言:

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

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

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

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

思路:

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

 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格式

 {
"retcode": ,
"retmsg": "成功",
"total": "",
"page": ,
"rn": ,
"data": [
{
"fid": "",
"fcover": "http://p0.qpic.cn/estate/0/cbcef0b36d585650ec602ebe0ca56a18.jpg/180",
"fname": "鸿坤·理想湾",
"faddress": "涿州东高铁新城涿州东站西侧300米",
"fregion": "大北京",
"fpricedisplaystr": "7200元/平米",
"faroundhighprice": ,
"faroundlowprice": ,
"groupbuynum": ,
"lng": "116.052084096376",
"lat": "39.4636526249295",
"fsellstatus": "",
"istencentdiscount": ,
"bookmark": [
{
"tag": "看房团",
"type":
},
{
"tag": "低总价",
"type":
},
{
"tag": "品牌开发商",
"type":
}
],
"price_pre": "均价",
"price_value": "",
"price_unit": "元/平米",
"panoid": "",
"heading": "",
"pitch": "",
"has_agent": ,
"hui":
},

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

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

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

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

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

代码:

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

先建一个房屋实体类

 package com.example.listview;

 public class Home {
private String name; public Home() {
super();
// TODO Auto-generated constructor stub
} public Home(String name) {
super();
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return name;
} }

Home.class

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

 package com.example.listview;

 import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; public class HttpUtil {
//将指定路径上的数据转换为字节数组形式返回
public static byte[] getByteJsonString(String path) throws IOException
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET"); //Get的连接方式
conn.setConnectTimeout();
conn.setDoInput(true);
if(conn.getResponseCode()==)// 响应码等于200表示连接成功
{
InputStream in = conn.getInputStream();
return getByteString(in);
}
return null; } public static byte[] getByteString(InputStream in) throws IOException
{
//内存流获取数据
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = ;
byte[] b = new byte[];
while((len = in.read(b))!=-)
{
//注意不要写成out.write(b); 否则若字节数据长度大于实际数据长度,后面部分乱码,导致后面json解析出错
out.write(b,,len);
} return out.toByteArray();
} }

HttpUtil.class

 package com.example.listview;

 import java.util.ArrayList;
import java.util.List; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; public class JsonString {
public static List getJsonResult(String json) throws JSONException
{
//JSON解析 ,解析某一城市下所有房屋的名字
List<Home> list = new ArrayList<Home>();
JSONObject obj = new JSONObject(json);
JSONArray arr = obj.getJSONArray("data");
Home home = null;
for(int i=;i<arr.length();i++)
{ JSONObject data = arr.getJSONObject(i);
home = new Home(); String fname =data.getString("fname");
home.setName(fname);
list.add(home);
}
return list; }
}

JsonString.class解析JSON数据

3、ListView的自定义适配器类

 package com.example.listview;

 import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView; public class MyAdapter extends BaseAdapter{ private Context context;
private List<Home> list; public MyAdapter(Context context)
{
this.context = context;
list = new ArrayList<Home>();
}
//关键点!
//将底部下拉刷新出来的数据(新解析出来的固定条数数据)添加到当前适配器中
public void addData(List lists){
list.addAll(lists);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
int count = ;
if(list!=null)
return list.size();
return count;
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = null;
if(convertView!=null)
{
view = convertView;
}
else
{
view = LayoutInflater.from(context).inflate(R.layout.layout_item,parent, false);
} ViewHolder holder = (ViewHolder) view.getTag();
if(holder==null)
{
holder = new ViewHolder();
holder.textview = (TextView) view.findViewById(R.id.id_textview);
view.setTag(holder);
}
holder.textview.setText(list.get(position).getName());
return view;
} class ViewHolder
{
TextView textview;
} }

MyAdapter.class

4、异步任务获得数据

 package com.example.listview;

 import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List; import org.json.JSONException; import android.os.AsyncTask; public class AsyncTaskHome extends AsyncTask<String, Void, List>{ private MyAdapter myadapter;
private List<Home> list ;
//将适配器作为参数传进来
public AsyncTaskHome(MyAdapter myadapter)
{
this.myadapter = myadapter;
}
@Override
protected List doInBackground(String... params) {
// TODO Auto-generated method stub
if(params[]!=null)
{
try {
String json = new String(HttpUtil.getByteJsonString(params[]),"utf-8");
list = JsonString.getJsonResult(json);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return list;
} @Override
protected void onPostExecute(List result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//将解析除的数据添加放入到当前适配器中
myadapter.addData(result);
//刷新适配器
myadapter.notifyDataSetChanged(); } }

AsyncTaskHome.class

5、主Activity

 package com.example.listview;

 import android.app.Activity;
import android.os.Bundle;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.Toast; public class MainActivity extends Activity { private ListView listview ;
private boolean isEnd; //判断列表是否滑动到底部
private int page = ;//显示第几页数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); listview = (ListView) findViewById(R.id.listview);
//创建一个自定义适配器对象
final MyAdapter adapter = new MyAdapter(this);
//将该适配器作为listView的数据源
listview.setAdapter(adapter);
//启动异步任务,先解析第一个页面的数据
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"); listview.setOnScrollListener(new OnScrollListener() { @Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
//如果滑動到末尾並且手指離開了界面,則加載新的數據源添加到適配器中
if(isEnd && scrollState==OnScrollListener.SCROLL_STATE_IDLE)
{
Toast.makeText(MainActivity.this, "努力加载中---", ).show(); //加载一个新的数据源,包含新的20条数据
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";
//执行异步任务,将当前的自定义适配器传进去,将解析的新的数据添加到当前视频日期中
new AsyncTaskHome(adapter).execute(path);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
//如果已经划出去的列表项和正在显示的列表项==全部列表项,说明列表到达底部
isEnd = (firstVisibleItem+visibleItemCount)==totalItemCount;
}
}); } }

MainActivity.class

效果图:

安卓开发_浅谈ListView之分页列表的更多相关文章

  1. 安卓开发_浅谈ListView(SimpleAdapter数组适配器)

    安卓开发_浅谈ListView(ArrayAdapter数组适配器) 学习使用ListView组件和SimapleAdapter适配器实现一个带图标的ListView列表 总共3部分 一.MainAc ...

  2. 安卓开发_浅谈ListView(自定义适配器)

    ListView作为一个实际开发中使用率非常高的视图,一般的系统自带的适配器都无法满足开发中的需求,这时候就需要开发人员来自定义适配器使得ListView能够有一个不错的显示效果 有这样一个Demo ...

  3. 安卓开发_浅谈ListView(ArrayAdapter数组适配器)

    列表视图(ListView)以垂直的形式列出需要显示的列表项. 实现过程:新建适配器->添加数据源到适配器->视图加载适配器 在安卓中,有两种方法可以在屏幕中添加列表视图 1.直接用Lis ...

  4. 安卓开发_浅谈Android动画(四)

    Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1.  ValueAnimator 基本属 ...

  5. 安卓开发_浅谈Fragment之ListFragment

    ListFragment,即Fragment的一个子类,当我们用的一个Fragment只需要一个listview视图的时候使用 该类有几个特点: 1.ListFragment 本身具只有一个ListV ...

  6. 安卓开发_浅谈ContextMenu(上下文菜单)

    长下文菜单,即长按view显示一个菜单栏 与OptionMenu的区别OptionMenu对应的是activity,一个activity只能拥有一个选项菜单ContextMenu对应的是View,每个 ...

  7. 安卓开发_浅谈OptionsMenus(选项菜单)

    Android平台下所提供的菜单大体上可分为三类:选项菜单.上下文菜单和子菜单. 当Activity在前台运行时,如果用户按下手机上的Menu键,此时就会在屏幕低端弹出相应的选项菜单.但这个功能需要开 ...

  8. 安卓开发_浅谈Android动画(三)

    一.LayoutAnimation布局动画 用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果 在res-anim文件下新建一个动画xml文件 <?xml ve ...

  9. 安卓开发_浅谈Action Bar

    一.Action Bar 导航栏.是3.0之后出现的. 所以注意使用的时候清单文件要设置下 android:minSdkVersion="11"(至少11) 但如果使用v4包,则不 ...

随机推荐

  1. 带你走进CSS定位详解

    学习CSS相关知识,定位是其中的重点,也是难点之一,如果不了解css定位有时候都不知道怎么用,下面整理了一下关于定位属性的具体理解和应用方案. 一:定位 定位属性列表 position top bot ...

  2. box-sizing:border-box的作用

    其实一直没仔细研究过CSS3新增的这个属性box-sizing,只是经常会看到其它网页和公司项目里面有用到这个属性,然后就百度找到了一篇不错的介绍 https://www.jianshu.com/p/ ...

  3. 凉凉了,Eureka 宣布闭源,Spring Cloud 何去何从?

    今年 Dubbo 活了,并且被 Apache 收了.同时很不幸,Spring Cloud 下的 Netflix Eureka 组件项目居然宣布闭源了.. 已经从 Dubbo 迁移至 Spring Cl ...

  4. python(32)——【shelve模块】【xml模块】

    一. shelve模块 json和pickle模块的序列化和反序列化处理,他们有一个不足是在python 3中不能多次dump和load,shelve模块则可以规避这个问题. shelve模块是一个简 ...

  5. iOS- XKZoomingView 简单的图片缩放预览,支持横屏、长图【手势:单击、双击、放大缩小】

    XKZoomingView.h #import <UIKit/UIKit.h> @interface XKZoomingView : UIScrollView /** 本地图片 */ @p ...

  6. 在Vue中使用CodeMirror 格式显示错误 行数错乱 & 代码隐藏

    项目需要在线展示和编辑Json文件,所以需要找一个代码编辑器,因为我们的项目直接使用的 vueAdmin-template 这个模板 json编辑器也是直接从 vue-element-admin 项目 ...

  7. C语言实现多态

    C语言实现多态 首先声明,大神就不要看了.小弟水平有限. C++多态是通过虚函数表实现的,类似于JAVA多态的实现方式.关于Java多态的实现方式可以看我之前写过的一篇不是很完善的文章.从JVM角度看 ...

  8. leetcode — longest-common-prefix

    /** * Source : https://oj.leetcode.com/problems/longest-common-prefix/ * * Created by lverpeng on 20 ...

  9. 自动化发布-GitLab WEB Hooks 配置

    钩子(hooks) hooks是在特定事件发生之前或之后执行特定脚本代码功能(从概念上类比,就与监听事件.触发器之类的东西类似). Git hooks就是那些在Git执行特定事件(如commit.pu ...

  10. vuejs深入浅出—基础篇

    一.从HelloWorld说起 任何语言的都是从Hello World开始的,VueJs也不例外,直接上代码: <script src="https://unpkg.com/vue/d ...