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

         

一般如果一个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. 201871010133-赵永军《面向对象程序设计(java)》第十二周学习总结

    201871010133-赵永军<面向对象程序设计(java)>第十二周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  2. Location配置与ReWrite语法(五)

    原文链接:https://www.cnblogs.com/crazylqy/p/6892010.html location表示uri方式定位,基础语法有三种: location = pattern { ...

  3. Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解

    Happy Birthday, Polycarp! Make Them Odd As Simple as One and Two Let's Play the Words? Two Fairs Bea ...

  4. <DFS & BFS> 130 127

    130. Surrounded Regions BFS: 把所有边界上的O先换成A(标记),再深度遍历周围的点. 最后把O换成X(表示不符合要求),所有的A换回O class Solution { p ...

  5. [BJOI2019]勘破神机(第一类斯特林数,斐波那契数列)

    真的是好题,只不过强行多合一有点过分了…… 题目大意: $T$ 组数据.每个测试点中 $m$ 相同. 对于每组数据,给定 $l,r,k$,请求出 $\dfrac{1}{r-l+1}\sum\limit ...

  6. [LeetCode] 718. Maximum Length of Repeated Subarray 最长的重复子数组

    Given two integer arrays A and B, return the maximum length of an subarray that appears in both arra ...

  7. Jupyter Notebook 访问密码重置

    试想你访问 Jupyter Notebook ,突然忘记了访问密码,该怎么做.经实践,只需利用命令行重新设置下密码即可. ## step 1:终端输入 jupyter notebook --gener ...

  8. windows远程复制中断无法复制

    关掉对应的rdpclip进程,再创建一个

  9. 日均5亿查询量的京东订单中心,为什么舍MySQL用ES?

    阅读本文大概需要 8 分钟. 来源:京东技术订阅号(ID:jingdongjishu) 作者:张sir   京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调 ...

  10. 慕课网springboot博客系统开发(一)----spring initializr的使用 gradle构建项目

    spring initializr工具的地址:https://start.spring.io/:通过它可以很方便的创建springboot项目 这里我们选择使用gradle作为项目的构建工具,此spr ...