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

         

一般如果一个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. oracle查看被锁的表及解除锁

    -- 查看被锁对象 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session ...

  2. 阿里云serverless使用笔记

    1.使用api网关服务,创建完api后,测试时,需要传“请求签名”,否则会报401 ‘Empty Signature’错误.相关文档<错误编码表,请求签名>.(错误信息放置与响应头的‘x- ...

  3. LG1410 子序列 二分图判定

    问题描述 LG1410 题解 如果\(i<j,a_j \le a_i\),那么他它们不能在一个上升序列中. 于是在\(i,j\)之间建边,看建出来的图是不是二分图即可. \(\mathrm{Co ...

  4. html表格及列表

    表格的属性: border:边框 cellpadding:内边距  单元格边框跟内容之间的间距 cellspacing:外边距  单元格跟单元格之间的距离 align:表格的对其样式 width:宽度 ...

  5. web框架--XSS攻击和CSRF请求伪造

    XSS 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往Web ...

  6. <Trie> 212 <Array> 229

    212. Word Search II class TrieNode{ char val; TrieNode[] children; String word; public TrieNode(char ...

  7. ASP.NET开发实战——(一)开篇-用VS创建一个ASP.NET Web程序

        本文是本系列文章第一篇,主要通过建立一个默认ASP.NET MVC项目来引出与ASP.NET MVC相关的功能,由于ASP.NET MVC一个简单的模板就具备了数据库操作.身份验证.输入数据校 ...

  8. js数组检测

    数组检测 检测constructor v.constructor === Array 缺点: let arr = [] console.log(arr.constructor === Array); ...

  9. 获取本地连接ip地址(通用版)

    @echo off & setlocal enabledelayedexpansionrem 如果系统中有route命令,优先采用方案1:for /f "tokens=3,4&quo ...

  10. HTTP协议,到底是什么鬼?

    作者 | Jeskson 来源 | 达达前端小酒馆 了解HTTP HTTP是什么呢?它是超文本传输协议,HTTP是缩写,它的全英文名是HyperText Transfer Protocol. 那么什么 ...