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

         

一般如果一个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. appium连接genymation运行计算器的例子

    #coding=utf-8from appium import webdriverdesired_caps={}desired_caps["platformName"]=" ...

  2. 莫烦TensorFlow_01 基本程序结构

    import tensorflow as tf import numpy as np # create data x_data = np.random.rand(100).astype(np.floa ...

  3. 快速安装Rainbond——开源企业级Paas平台

    快速安装Rainbond--开源企业级Paas平台 参考:https://www.rainbond.com/docs/user-operations/install/online_install/ R ...

  4. 基于Intel OpenVINO的搭建及应用,包含分类,目标检测,及分割,超分辨

    PART I: 搭建环境OPENVINO+Tensorflow1.12.0 I: l_openvino_toolkit_p_2019.1.094 第一步常规安装参考链接:https://docs.op ...

  5. Debian 9 部分快捷键失效问题

    教程 具体修复过程: 安装gnome-screensaver包,重启恢复正常.

  6. 【转】TCP/IP协议——ARP详解

    本文主要讲述了ARP的作用.ARP分组格式.ARP高速缓存.免费ARP和代理ARP. 1.学习ARP前要了解的内容 建立TCP连接与ARP的关系 应用接受用户提交的数据,触发TCP建立连接,TCP的第 ...

  7. Xamarin.Forms移动开发系列5 :XAML标记扩展

    摘要 本文主要讲述Xamarin.Forms中XAML的标记扩展. 前言 在Xamarin.Forms移动开发系列4 :XAML基础一文中提到过XAML标记扩展,本文将对标记扩展进行更深入的了解. 大 ...

  8. A1033 To Fill or Not to Fill (25 分)

    一.技术总结 是贪心算法的题目,题目主要考虑的问题有几个,是否会在第一个加油站的最近距离大于0,如果是这样那么直接输出答案,因为初始油箱没有汽油: 第二个是如何选定加油站,如果在可到达距离范围类,我们 ...

  9. Linux性能优化实战学习笔记:第三讲

    一.关于上下文切换的几个为什么 1. 上下文切换是什么? 上下文切换是对任务当前运行状态的暂存和恢复 2. CPU为什么要进行上下文切换? 当多个进程竞争CPU的时候,CPU为了保证每个进程能公平被调 ...

  10. orientation属性(判断是否为横竖屏)

    现在有一个需求:移动端网页默认竖屏显示,当用户横屏浏览,就给予相应提示,比如横屏时显示下面截图提示信息 几年前,可能大家想到用 window.orientation 属性来实现,现官方已弃用,不做推荐 ...