• Android 自定义ListView动态加载数据


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

             

    一般如果一个Activity集成越多的功能,代码量也会随之增多,看起来让人烦,我们可以考虑自定义控件将一些操作集成进去。

    自定义ListView

     1 package com.example.listviewdynamicloading;
     2 
     3 import android.content.Context;
     4 import android.util.AttributeSet;
     5 import android.view.LayoutInflater;
     6 import android.view.View;
     7 import android.widget.AbsListView;
     8 import android.widget.AbsListView.OnScrollListener;
     9 import android.widget.ListView;
    10 
    11 public class ZdyListView extends ListView implements OnScrollListener {
    12     private int totalItemCount;// 总数量;
    13     private int lastVisibleItem;// 最后一个可见的item;
    14     private boolean isLoading;
    15     private View footer;
    16     private LayoutInflater inflater;
    17     public RefleshDatas refleshDatas;
    18 
    19     public ZdyListView(Context context) {
    20         super(context);
    21         initView(context);
    22     }
    23 
    24     public ZdyListView(Context context, AttributeSet attrs) {
    25         super(context, attrs);
    26         initView(context);
    27     }
    28 
    29     public ZdyListView(Context context, AttributeSet attrs, int defStyle) {
    30         super(context, attrs, defStyle);
    31         initView(context);
    32     }
    33 
    34     private void initView(Context context) {
    35         footer=inflater.from(context).inflate(R.layout.layout_util_footer, null);
    36         this.setOnScrollListener(this);
    37         this.addFooterView(footer);
    38         this.removeFooterView(footer);
    39     }
    40 
    41     @Override
    42     public void onScroll(AbsListView view, int firstVisibleItem,
    43             int visibleItemCount, int totalItemCount) {
    44         this.lastVisibleItem = firstVisibleItem + visibleItemCount;
    45         this.totalItemCount = totalItemCount;
    46     }
    47 
    48     @Override
    49     public void onScrollStateChanged(AbsListView view, int scrollState) {
    50         //listview item总数量等于最后一个可见的item并且ListView停下不动了
    51         if (totalItemCount == lastVisibleItem&& scrollState == SCROLL_STATE_IDLE) {
    52             if (!isLoading) {
    53                 isLoading = true;
    54                 this.addFooterView(footer);
    55                 if (refleshDatas != null) {      
    56                     //回调执行向服务器端请求数据
    57                     refleshDatas.onLoading();
    58                 }  
    59             }
    60         }
    61     };
    62     public void loadComplete() {
    63         isLoading = false;
    64         this.removeFooterView(footer);//加载完毕,移除footView;
    65     }
    66     public void setInterface(RefleshDatas refleshDatas) {
    67         this.refleshDatas = refleshDatas;
    68     }
    69     public interface RefleshDatas{
    70         public void onLoading();
    71     }
    72 }

    MainActivity

      1 package com.example.listviewdynamicloading;
      2 
      3 import java.util.ArrayList;
      4 
      5 import com.example.listviewdynamicloading.ZdyListView.RefleshDatas;
      6 
      7 import android.app.Activity;
      8 import android.os.Bundle;
      9 import android.os.Handler;
     10 import android.os.Message;
     11 import android.view.Menu;
     12 import android.view.MenuItem;
     13 import android.widget.ListView;
     14 import android.widget.Toast;
     15 
     16 public class MainActivity extends Activity{
     17     //一次从服务器端请求十条数据
     18     private int current=1;  
     19     private int number=9;
     20     
     21     
     22     private ZdyListView listView; //自定义ListView,将footview,滑动监听等集合在一起,免得Activity代码过多
     23     private ArrayList<String> listDatas;
     24     private ListViewAdapter adapter;
     25 
     26 
     27     private Handler handler=new Handler(){
     28         public void handleMessage(android.os.Message msg) {
     29             switch (msg.what) {
     30             case 0x123:
     31                 setlistView((ArrayList<String>)msg.obj,"firstLoading");//firstLoading标志位代表数据是初次加载的
     32                 break;
     33             case 0x234:
     34                 setlistView((ArrayList<String>)msg.obj,"addLoading");//addLoading标志位代表数据是初次加载之后请求服务器所得
     35                 break;
     36             case 0x345:
     37                 showMsg((String)msg.obj);
     38                 break;
     39             default:
     40                 break;
     41             }
     42         };
     43     };
     44 
     45     @Override
     46     protected void onCreate(Bundle savedInstanceState) {
     47         super.onCreate(savedInstanceState);
     48         setContentView(R.layout.activity_main);
     49         listDatas=new ArrayList<String>();
     50         listView=(ZdyListView) this.findViewById(R.id.listview);
     51         listView.setInterface(new RefleshDatas() {
     52             @Override
     53             public void onLoading() {
     54                 getDataThread(current, current+number, "addLoading");
     55             }
     56         });
     57     }
     58 
     59 
     60 
     61     @Override
     62     protected void onStart() {
     63         super.onStart();
     64         getDataThread(current,number,"firstLoading");
     65     }
     66 
     67     //.........................模拟开启线程向服务器请求数据.....................................
     68     private void getDataThread(final int current, final int number,final String type) {
     69         final Message msg=new Message();
     70         new Thread(){
     71             public void run() {
     72                 ArrayList<String> datas=ListViewDatas.returnNum(current, current+number);
     73                 if(datas!=null&&datas.size()>0){
     74                     switch (type) {
     75                     case "firstLoading":
     76                         msg.what=0x123;
     77                         break;
     78                     case "addLoading":
     79                         msg.what=0x234;
     80                         break;
     81                     default:
     82                         break;
     83                     }    
     84                     msg.obj=datas;
     85                 }else {
     86                     msg.what=0x345;
     87                     msg.obj=datas;
     88                 }
     89                 handler.sendMessage(msg);
     90             };
     91         }.start();
     92     }
     93 
     94 
     95 
     96     private void setlistView(ArrayList<String> datas,String type) {
     97         listDatas.addAll(datas);
     98         if(type.equals("firstLoading")){//初次加载
     99             adapter=new ListViewAdapter(MainActivity.this, listDatas);
    100             current=adapter.getCount()+1;
    101             listView.setAdapter(adapter);
    102             listView.loadComplete();
    103         }else if(type.equals("addLoading")){//初次加载后请求的数据,执行notifyDataSetChanged();
    104             adapter.notifyDataSetChanged();
    105             current=adapter.getCount()+1;
    106             listView.loadComplete();
    107         }
    108     }
    109 
    110 
    111     protected void showMsg(String str) {
    112         Toast.makeText(MainActivity.this, "已加载完毕", Toast.LENGTH_SHORT).show();
    113         listView.loadComplete();
    114     }
    115 
    116 
    117 
    118 }

    模拟服务器端数据

     1 package com.example.listviewdynamicloading;
     2 
     3 import java.util.ArrayList;
     4 
     5 public class ListViewDatas {
     6     //模拟服务器端数据库中的数据,假设现在只有3条数据
     7     public static int NUM=53;
     8     public static ArrayList<String> returnNum(int startNum,int endNum){
     9         ArrayList<String> list=new ArrayList<String>();
    10         if(endNum<=NUM){//客户端请求的数据在数据库数据范围之内
    11             for(int i=startNum;i<=endNum;i++){
    12                 list.add(String.valueOf(i));
    13             }
    14             return list;
    15         }else if(endNum>=NUM&&startNum<=NUM){//客户端请求的数据不全在数据库数据范围之内
    16             for(int i=startNum;i<=NUM;i++){
    17                 list.add(String.valueOf(i));
    18             }
    19             return list;            
    20         }else if(startNum>NUM){//客户端请求的数据超出数据库数据范围之内
    21             return null;
    22         }
    23         return null;
    24     }
    25 }

    ListView适配器

     1 package com.example.listviewdynamicloading;
     2 
     3 import java.util.ArrayList;
     4 
     5 import android.content.Context;
     6 import android.view.LayoutInflater;
     7 import android.view.View;
     8 import android.view.ViewGroup;
     9 import android.widget.BaseAdapter;
    10 import android.widget.TextView;
    11 
    12 public class ListViewAdapter extends BaseAdapter{
    13     private Context context;
    14     private ArrayList<String> datas;
    15 
    16     public ListViewAdapter(Context context,ArrayList<String> datas){
    17         this.context=context;
    18         this.datas=datas;
    19     }
    20     
    21     @Override
    22     public int getCount() {
    23         return datas.size();
    24     }
    25 
    26     @Override
    27     public Object getItem(int position) {
    28         return null;
    29     }
    30 
    31     @Override
    32     public long getItemId(int position) {
    33         return position;
    34     }
    35 
    36     @Override
    37     public View getView(int position, View convertView, ViewGroup parent) {
    38         ViewHolder vh=null;
    39         if(convertView==null){
    40             vh=new ViewHolder();
    41             convertView=LayoutInflater.from(context).inflate(R.layout.listview_item, null);
    42             vh.tv=(TextView) convertView.findViewById(R.id.tv);
    43             convertView.setTag(vh);
    44         }else {
    45             vh=(ViewHolder) convertView.getTag();
    46         }
    47         vh.tv.setText("这是第"+datas.get(position)+"条数据");
    48         return convertView;
    49     }
    50     
    51     
    52     
    53     class ViewHolder{
    54         TextView tv;
    55     }
    56 
    57 
    58 }
  • 相关阅读:
    [BZOJ1657] [Usaco2006 Mar] Mooo 奶牛的歌声 (单调栈)
    [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
    [BZOJ1015] [JSOI2008] 星球大战starwar (并查集)
    [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)
    [BZOJ1061] [Noi2008] 志愿者招募 (费用流)
    [BZOJ1051] [HAOI2006] 受欢迎的牛 (强联通分量)
    BZOJ2299: [HAOI2011]向量
    BZOJ2783: [JLOI2012]树
    BZOJ3521: [Poi2014]Salad Bar
    BZOJ2429: [HAOI2006]聪明的猴子
  • 原文地址:https://www.cnblogs.com/bdsdkrb/p/5020908.html
Copyright © 2020-2023  润新知