Android 自定义ListView动态加载数据
我们都知道网络取数据是耗时操作,如果我们一次性请求所有数据,假如数据量不多那还可以接受,但是如果数据量特别多,那么带来的后果就是用户的愤怒(用户是很没有耐心的),所以这时候我们就需要动态的加载数据,分批加载我们所需的数据,提升用户体验,先上图。

一般如果一个Activity集成越多的功能,代码量也会随之增多,看起来让人烦,我们可以考虑自定义控件将一些操作集成进去。
自定义ListView
package com.example.listviewdynamicloading; import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView; public class ZdyListView extends ListView implements OnScrollListener {
private int totalItemCount;// 总数量;
private int lastVisibleItem;// 最后一个可见的item;
private boolean isLoading;
private View footer;
private LayoutInflater inflater;
public RefleshDatas refleshDatas; public ZdyListView(Context context) {
super(context);
initView(context);
} public ZdyListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
} public ZdyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
} private void initView(Context context) {
footer=inflater.from(context).inflate(R.layout.layout_util_footer, null);
this.setOnScrollListener(this);
this.addFooterView(footer);
this.removeFooterView(footer);
} @Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.lastVisibleItem = firstVisibleItem + visibleItemCount;
this.totalItemCount = totalItemCount;
} @Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//listview item总数量等于最后一个可见的item并且ListView停下不动了
if (totalItemCount == lastVisibleItem&& scrollState == SCROLL_STATE_IDLE) {
if (!isLoading) {
isLoading = true;
this.addFooterView(footer);
if (refleshDatas != null) {
//回调执行向服务器端请求数据
refleshDatas.onLoading();
}
}
}
};
public void loadComplete() {
isLoading = false;
this.removeFooterView(footer);//加载完毕,移除footView;
}
public void setInterface(RefleshDatas refleshDatas) {
this.refleshDatas = refleshDatas;
}
public interface RefleshDatas{
public void onLoading();
}
}
MainActivity
package com.example.listviewdynamicloading; import java.util.ArrayList; import com.example.listviewdynamicloading.ZdyListView.RefleshDatas; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.Toast; public class MainActivity extends Activity{
//一次从服务器端请求十条数据
private int current=1;
private int number=9; private ZdyListView listView; //自定义ListView,将footview,滑动监听等集合在一起,免得Activity代码过多
private ArrayList<String> listDatas;
private ListViewAdapter adapter; private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0x123:
setlistView((ArrayList<String>)msg.obj,"firstLoading");//firstLoading标志位代表数据是初次加载的
break;
case 0x234:
setlistView((ArrayList<String>)msg.obj,"addLoading");//addLoading标志位代表数据是初次加载之后请求服务器所得
break;
case 0x345:
showMsg((String)msg.obj);
break;
default:
break;
}
};
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listDatas=new ArrayList<String>();
listView=(ZdyListView) this.findViewById(R.id.listview);
listView.setInterface(new RefleshDatas() {
@Override
public void onLoading() {
getDataThread(current, current+number, "addLoading");
}
});
} @Override
protected void onStart() {
super.onStart();
getDataThread(current,number,"firstLoading");
} //.........................模拟开启线程向服务器请求数据.....................................
private void getDataThread(final int current, final int number,final String type) {
final Message msg=new Message();
new Thread(){
public void run() {
ArrayList<String> datas=ListViewDatas.returnNum(current, current+number);
if(datas!=null&&datas.size()>0){
switch (type) {
case "firstLoading":
msg.what=0x123;
break;
case "addLoading":
msg.what=0x234;
break;
default:
break;
}
msg.obj=datas;
}else {
msg.what=0x345;
msg.obj=datas;
}
handler.sendMessage(msg);
};
}.start();
} private void setlistView(ArrayList<String> datas,String type) {
listDatas.addAll(datas);
if(type.equals("firstLoading")){//初次加载
adapter=new ListViewAdapter(MainActivity.this, listDatas);
current=adapter.getCount()+1;
listView.setAdapter(adapter);
listView.loadComplete();
}else if(type.equals("addLoading")){//初次加载后请求的数据,执行notifyDataSetChanged();
adapter.notifyDataSetChanged();
current=adapter.getCount()+1;
listView.loadComplete();
}
} protected void showMsg(String str) {
Toast.makeText(MainActivity.this, "已加载完毕", Toast.LENGTH_SHORT).show();
listView.loadComplete();
} }
模拟服务器端数据
package com.example.listviewdynamicloading;
import java.util.ArrayList;
public class ListViewDatas {
//模拟服务器端数据库中的数据,假设现在只有3条数据
public static int NUM=53;
public static ArrayList<String> returnNum(int startNum,int endNum){
ArrayList<String> list=new ArrayList<String>();
if(endNum<=NUM){//客户端请求的数据在数据库数据范围之内
for(int i=startNum;i<=endNum;i++){
list.add(String.valueOf(i));
}
return list;
}else if(endNum>=NUM&&startNum<=NUM){//客户端请求的数据不全在数据库数据范围之内
for(int i=startNum;i<=NUM;i++){
list.add(String.valueOf(i));
}
return list;
}else if(startNum>NUM){//客户端请求的数据超出数据库数据范围之内
return null;
}
return null;
}
}
ListView适配器
package com.example.listviewdynamicloading; import java.util.ArrayList; 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 ListViewAdapter extends BaseAdapter{
private Context context;
private ArrayList<String> datas; public ListViewAdapter(Context context,ArrayList<String> datas){
this.context=context;
this.datas=datas;
} @Override
public int getCount() {
return datas.size();
} @Override
public Object getItem(int position) {
return null;
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh=null;
if(convertView==null){
vh=new ViewHolder();
convertView=LayoutInflater.from(context).inflate(R.layout.listview_item, null);
vh.tv=(TextView) convertView.findViewById(R.id.tv);
convertView.setTag(vh);
}else {
vh=(ViewHolder) convertView.getTag();
}
vh.tv.setText("这是第"+datas.get(position)+"条数据");
return convertView;
} class ViewHolder{
TextView tv;
} }
Android 自定义ListView动态加载数据的更多相关文章
- Android中ListView动态加载数据
1. 引言: 为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采取分批加载策略,随着用户的滑动,动态的从后台加载所需的 ...
- AppCan学习笔记----关闭页面listview动态加载数据
AppCan页面关闭 AppCan 的页面是由两个HTML组成,如果要完全关闭的话需要在主HTML eg.index.html中关闭,关闭方法:appcan.window.close(-1); 管道 ...
- 分享个刚写好的 android 的 ListView 动态加载类,功能全而代码少。
(转载声明出处:http://www.cnblogs.com/linguanh/) 简介: 该ListView 实现动态加载数据,为了方便用户充分地自定义自己的数据源.点击事件,等核心操作, ...
- Android中ListView分页加载数据
public class MainActivity extends Activity { private ListView listView=null; //listview的数据填充器 privat ...
- Android Scrollview嵌套下listView动态加载数据,解决onScrollChanged执行多次数据重复问题
这一篇博客和上一篇讲的都是listView的动态加载,但有所不同的是,本篇的listView是嵌套在ScrollView下的,有时候在一个Activity中可能分为好几个模块,由于展示的需要(手机屏幕 ...
- Android中ListView异步加载数据
1.主Activity public class MainActivity extends Activity { private ListView listView; private ArrayLis ...
- 【Android进阶】Listview分页加载数据的实现
Listview分页加载数据的实现 public class MainActivity extends Activity { protected static final int SUCCESS_GE ...
- Android中的动态加载机制
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法
Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...
随机推荐
- 【Oracle】Windows启动
cd D:\app\Administrator\product\\dbhome_1\BIN D: sqlplus /nolog conn sys/system as sysdba startup pf ...
- Mybatis-Plus 代码生成器基本使用
Mybatis-Plus 代码生成器基本使用 参考 https://mp.baomidou.com/guide/generator.html#%E4%BD%BF%E7%94%A8%E6%95%99%E ...
- 003VlookUp的使用
在Excel中,Vlookup这个函数还是挺有用的 我最近在一个场景中使用到VlookUp函数,使用场景是 我们将学生名单导入到学业上报系统的时候,发现Excel中有 79条数据但是导入成功的提示是说 ...
- numpy cookbook
1.第一章 import numpy as np import matplotlib.pyplot as plt import scipy import PIL import scipy.misc l ...
- JS判断是否是ioS或者Android
每个客户端都带有自身的UA标识,通过JavaScript,可以获取客户端标识,我们可以获取浏览器的userAgent,用正则来判断手机是ios(苹果)还是Android(安卓)客户端. 项目实例:ht ...
- B1005 继续(3n+1)猜想 (25 分)
一.技术总结 一个是注意输出格式,也就是末尾没有空格,这个解决方法一般是使用一个计数,然后打印输出一个就减少一个. 就是在使用数组时,要注意段错误,也就是数组开辟的是否够大. 如果可以的话,可以多设置 ...
- [LeetCode] 1028. Recover a Tree From Preorder Traversal 从先序遍历还原二叉树
We run a preorder depth first search on the rootof a binary tree. At each node in this traversal, we ...
- 关于Dev-C++用户所必须知道的知识
开启这几个警告选项,才能拥有GCC编译器的较为全面的报错和警告 另外,目前Dev-C早已停止更新(停滞在版本号5.1,内置的GCC为4.9版本),且使用其检测数组变量也挺麻烦的,实在不推荐使用.
- js 为url字符串添加、修改参数
//为url字符串添加.修改参数 String.prototype.EditUrlParam = function (paramName, replaceWith) { var url = this; ...
- 判断一个类型是否为可空类型 System Nullable
bool IsNullableType(Type theType) { return (theType.IsGenericType && theType. G ...