zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/bdsdkrb/p/5020908.html
Copyright © 2011-2022 走看看