安卓开发_浅谈ListView之分页列表
前言:
在开发的过程中,有时候我们需要从网络解析一些数据,比如最近的一些新闻,我们需要把这些数据用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之分页列表的更多相关文章
- 安卓开发_浅谈ListView(SimpleAdapter数组适配器)
安卓开发_浅谈ListView(ArrayAdapter数组适配器) 学习使用ListView组件和SimapleAdapter适配器实现一个带图标的ListView列表 总共3部分 一.MainAc ...
- 安卓开发_浅谈ListView(自定义适配器)
ListView作为一个实际开发中使用率非常高的视图,一般的系统自带的适配器都无法满足开发中的需求,这时候就需要开发人员来自定义适配器使得ListView能够有一个不错的显示效果 有这样一个Demo ...
- 安卓开发_浅谈ListView(ArrayAdapter数组适配器)
列表视图(ListView)以垂直的形式列出需要显示的列表项. 实现过程:新建适配器->添加数据源到适配器->视图加载适配器 在安卓中,有两种方法可以在屏幕中添加列表视图 1.直接用Lis ...
- 安卓开发_浅谈Android动画(四)
Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1. ValueAnimator 基本属 ...
- 安卓开发_浅谈Fragment之ListFragment
ListFragment,即Fragment的一个子类,当我们用的一个Fragment只需要一个listview视图的时候使用 该类有几个特点: 1.ListFragment 本身具只有一个ListV ...
- 安卓开发_浅谈ContextMenu(上下文菜单)
长下文菜单,即长按view显示一个菜单栏 与OptionMenu的区别OptionMenu对应的是activity,一个activity只能拥有一个选项菜单ContextMenu对应的是View,每个 ...
- 安卓开发_浅谈OptionsMenus(选项菜单)
Android平台下所提供的菜单大体上可分为三类:选项菜单.上下文菜单和子菜单. 当Activity在前台运行时,如果用户按下手机上的Menu键,此时就会在屏幕低端弹出相应的选项菜单.但这个功能需要开 ...
- 安卓开发_浅谈Android动画(三)
一.LayoutAnimation布局动画 用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果 在res-anim文件下新建一个动画xml文件 <?xml ve ...
- 安卓开发_浅谈Action Bar
一.Action Bar 导航栏.是3.0之后出现的. 所以注意使用的时候清单文件要设置下 android:minSdkVersion="11"(至少11) 但如果使用v4包,则不 ...
随机推荐
- 没有安装hiredis
在redis的发行包中的deps目录中就包含hiredis的源码,手动编译安装,或者自行下载一份.地址:hiredis的地址 cd /deps/hiredis make make install 然后 ...
- hashcode和equals方法的区别和联系
说到 hashcode就要和Java中的集合,HashSet,HashMap 关系最为密切. 首先附录两张Java的集合结构图: 图二:(上图的简化版) 从Set集合的特点说起 & Set是如 ...
- 关于vue-router,路由重定向的使用分析
看之前的项目,突然发现一个不算bug的bug,之前也是一直没有想到,现在发现之后越来越觉得有必要改掉, 项目用的是vue做的,自然切换用的就是路由,一级路由包括:首页.记录和个人中心,二级路由是在记录 ...
- 关于 Spring Security 5 默认使用 Password Hash 算法
账户密码存储的安全性是一个很老的话题,但还是会频频发生,一般的做法是 SHA256(userInputpwd+globalsalt+usersalt) 并设置密码时时要求长度与大小写组合,一般这样设计 ...
- Android invalidate()方法 requestLayout()方法分析
强调一点的就是,在onMeasure(),onLayout(),onDraw()这三个流程中,Google已经帮我们把draw()过程框架已经写好了,自定义的ViewGroup只需要实现 measur ...
- android_安装包_NoClassDefFoundError
说说这个问题出现的地方吧: 能够成功的打包安装包,但是在安装包安装后,准备运行时出现了这个问题. 查看了这篇文章,讲得有理有据,并没有解决我的问题. 通过谷歌查找到这个stackoverflow,解决 ...
- 让Java线程池实现任务阻塞执行的一种可行方案
Java的线程池一般是基于concurrent包下的ThreadPoolExecutor类实现的, 不过当我们基于spring框架开发程序时, 通常会使用其包装类ThreadPoolTaskExecu ...
- eclipse配置ant开发环境,一键部署项目
ANT出现之前,编译和部署Java应用需要使用包括特定平台的脚本.Make文件.不同的IDE以及手工操作等组成的大杂烩.现在,几乎所有的开源Java项目都在使用Ant,许多公司的开发项目也在使用Ant ...
- SaltStack数据系统-Pillar详解
1:存储位置 存储在master端,存放需要提供给minion的信息 每个minion只能访问master分配给自己的(应用场景) 2:在centos7 salt 2015.5.10 (Lithium ...
- oracle中if/else的三种实现方式
1.标准sql规范 .单个IF IF v=... THEN END IF; .IF ... ELSE IF v=... THEN ELSE t....; END IF; .多个IF IF v=... ...