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

         

一般如果一个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动态加载数据的更多相关文章

  1. Android中ListView动态加载数据

    1. 引言: 为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采取分批加载策略,随着用户的滑动,动态的从后台加载所需的 ...

  2. AppCan学习笔记----关闭页面listview动态加载数据

    AppCan页面关闭 AppCan 的页面是由两个HTML组成,如果要完全关闭的话需要在主HTML eg.index.html中关闭,关闭方法:appcan.window.close(-1); 管道 ...

  3. 分享个刚写好的 android 的 ListView 动态加载类,功能全而代码少。

    (转载声明出处:http://www.cnblogs.com/linguanh/) 简介:      该ListView 实现动态加载数据,为了方便用户充分地自定义自己的数据源.点击事件,等核心操作, ...

  4. Android中ListView分页加载数据

    public class MainActivity extends Activity { private ListView listView=null; //listview的数据填充器 privat ...

  5. Android Scrollview嵌套下listView动态加载数据,解决onScrollChanged执行多次数据重复问题

    这一篇博客和上一篇讲的都是listView的动态加载,但有所不同的是,本篇的listView是嵌套在ScrollView下的,有时候在一个Activity中可能分为好几个模块,由于展示的需要(手机屏幕 ...

  6. Android中ListView异步加载数据

    1.主Activity public class MainActivity extends Activity { private ListView listView; private ArrayLis ...

  7. 【Android进阶】Listview分页加载数据的实现

    Listview分页加载数据的实现 public class MainActivity extends Activity { protected static final int SUCCESS_GE ...

  8. Android中的动态加载机制

    在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...

  9. Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法

    Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...

随机推荐

  1. 201871010118-唐敬博 《面向对象程序设计(java)》第十五周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 <https://www.cnblogs.com/nwnu-daizh/> 这个作业的要求在哪里 <https://ww ...

  2. Nginx ServerName 配置说明

    Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了.下面我就来说说server_name的使用吧:ser ...

  3. django学习-管理界面、视图

    django管理界面 设计背景 为你的员工或客户生成一个用户添加,修改和删除内容的后台是一项缺乏创造性和乏味的工作.因此,django全自动地根据模型创建后台界面. django产生于一个公众页面和内 ...

  4. Linux系统下root密码遗忘等系统故障的修复方法 - 运维总结

    IDC机房有一台centos系统的服务器,由于这台服务器的系统装了好长时间,且root密码中间更新过几次,后面去机房现场维护时,登陆密码遗忘了,悲催啊~没办法,只能开机进入“单用户模式”进行密码重置了 ...

  5. js将字符串内空格去除的方法

    function noSpace(x){ if(x.match(/\s*/g)){ return x.replace(/\s*/g,""); }else{ return x; } ...

  6. 第02组 Beta冲刺(4/4)

    队名:十一个憨批 组长博客 作业博客 组长黄智 过去两天完成的任务:了解整个游戏的流程 GitHub签入记录 接下来的计划:继续完成游戏 还剩下哪些任务:完成游戏 燃尽图 遇到的困难:没有美术比较好的 ...

  7. MySQL实战45讲学习笔记:第二十三讲

    一.本节概要 今天这篇文章,我会继续和你介绍在业务高峰期临时提升性能的方法.从文章标题“MySQL 是怎么保证数据不丢的?”,你就可以看出来,今天我和你介绍的方法,跟数据的可靠性有关. 在专栏前面文章 ...

  8. Node.js安装使用-VueCLI安装使用-工程化的Vue.js开发

    作者 | Jeskson 来源 | 达达前端小酒馆 搭建Node.js环境 什么是Node.js简介呢?它是一个基于JavaScript的运行环境,Node.js发布于2009年5月,对Chrome ...

  9. (十六)golang--匿名函数

    Go支持匿名函数,如果我们某个函数只是使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用: 匿名函数的使用方式:(1)在定义匿名函数的时候就直接调用,这种方式匿名函数只调用一次: (2)将匿名 ...

  10. Nodejs操作MySQL数据库

    https://github.com/mysqljs/mysql   如何用nodejs操作MySql数据呢,其实写法还是简单的, 1.开始在你的node项目中 npm install mysql - ...