android上拉下拉加载更多数据

简介: 最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例。 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view;    import java.util.D
最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例。


效果图

下拉刷新:


加载更多:



CustomListView.java

  1. package com.example.uitest.view;  
  2.   
  3. import java.util.Date;  
  4. import com.example.uitest.R;  
  5. import android.content.Context;  
  6. import android.util.AttributeSet;  
  7. import android.util.Log;  
  8. import android.view.LayoutInflater;  
  9. import android.view.MotionEvent;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.view.animation.LinearInterpolator;  
  13. import android.view.animation.RotateAnimation;  
  14. import android.widget.AbsListView;  
  15. import android.widget.AbsListView.OnScrollListener;  
  16. import android.widget.BaseAdapter;  
  17. import android.widget.ImageView;  
  18. import android.widget.LinearLayout;  
  19. import android.widget.ListView;  
  20. import android.widget.ProgressBar;  
  21. import android.widget.TextView;  
  22.   
  23. /** 
  24.  * ListView下拉刷新 
  25.  * 
  26.  */  
  27. public class CustomListView extends ListView implements OnScrollListener {  
  28.   
  29.     private final static int RELEASE_To_REFRESH = 0;  
  30.     private final static int PULL_To_REFRESH = 1;  
  31.     private final static int REFRESHING = 2;  
  32.     private final static int DONE = 3;  
  33.     private final static int LOADING = 4;  
  34.   
  35.     // 实际的padding的距离与界面上偏移距离的比例  
  36.     private final static int RATIO = 3;  
  37.   
  38.     private LayoutInflater inflater;  
  39.   
  40.     private LinearLayout headView;  
  41.   
  42.     private TextView tipsTextview;  
  43.     private TextView lastUpdatedTextView;  
  44.     private ImageView arrowImageView;  
  45.     private ProgressBar progressBar;  
  46.   
  47.   
  48.     private RotateAnimation animation;  
  49.     private RotateAnimation reverseAnimation;  
  50.   
  51.     // 用于保证startY的值在一个完整的touch事件中只被记录一次  
  52.     private boolean isRecored;  
  53.   
  54.     private int headContentWidth;  
  55.     private int headContentHeight;  
  56.   
  57.     private int startY;  
  58.     private int firstItemIndex;  
  59.   
  60.     private int state;  
  61.   
  62.     private boolean isBack;  
  63.   
  64.     private OnRefreshListener refreshListener;  
  65.     private OnLoadListener loadListener;  
  66.   
  67.     private boolean isRefreshable;  
  68.       
  69.     private ProgressBar moreProgressBar;  
  70.     private TextView loadMoreView;  
  71.     private View moreView;  
  72.   
  73.     public CustomListView(Context context) {  
  74.         super(context);  
  75.         init(context);  
  76.     }  
  77.   
  78.     public CustomListView(Context context, AttributeSet attrs) {  
  79.         super(context, attrs);  
  80.         init(context);  
  81.     }  
  82.   
  83.     private void init(Context context) {  
  84.         setCacheColorHint(context.getResources().getColor(R.color.transparent));  
  85.         inflater = LayoutInflater.from(context);  
  86.   
  87.         headView = (LinearLayout) inflater.inflate(R.layout.head, null);  
  88.   
  89.         arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);  
  90.         arrowImageView.setMinimumWidth(70);  
  91.         arrowImageView.setMinimumHeight(50);  
  92.         progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);  
  93.         tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);  
  94.         lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);  
  95.   
  96.         measureView(headView);  
  97.         headContentHeight = headView.getMeasuredHeight();  
  98.         headContentWidth = headView.getMeasuredWidth();  
  99.   
  100.         headView.setPadding(0, -1 * headContentHeight, 00);  
  101.         headView.invalidate();  
  102.   
  103.         Log.v("size""width:" + headContentWidth + " height:" + headContentHeight);  
  104.   
  105.         addHeaderView(headView, nullfalse);  
  106.         setOnScrollListener(this);  
  107.   
  108.         animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  109.         animation.setInterpolator(new LinearInterpolator());  
  110.         animation.setDuration(250);  
  111.         animation.setFillAfter(true);  
  112.   
  113.         reverseAnimation = new RotateAnimation(-1800, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  114.         reverseAnimation.setInterpolator(new LinearInterpolator());  
  115.         reverseAnimation.setDuration(200);  
  116.         reverseAnimation.setFillAfter(true);  
  117.   
  118.         state = DONE;  
  119.         isRefreshable = false;  
  120.           
  121.         moreView = LayoutInflater.from(context).inflate(R.layout.listfooter_more, null);  
  122.         moreView.setVisibility(View.VISIBLE);  
  123.         moreProgressBar = (ProgressBar) moreView.findViewById(R.id.pull_to_refresh_progress);  
  124.         loadMoreView = (TextView) moreView.findViewById(R.id.load_more);  
  125.         moreView.setOnClickListener(new View.OnClickListener() {  
  126.               
  127.             @Override  
  128.             public void onClick(View v) {  
  129.                 onLoad();  
  130.             }  
  131.         });  
  132.         addFooterView(moreView);  
  133.     }  
  134.   
  135.     public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2, int arg3) {  
  136.         firstItemIndex = firstVisiableItem;  
  137.     }  
  138.   
  139.     public void onScrollStateChanged(AbsListView arg0, int arg1) {  
  140.           
  141.     }  
  142.   
  143.     public boolean onTouchEvent(MotionEvent event) {  
  144.   
  145.         if (isRefreshable) {  
  146.             switch (event.getAction()) {  
  147.             case MotionEvent.ACTION_DOWN:  
  148.                 if (firstItemIndex == 0 && !isRecored) {  
  149.                     isRecored = true;  
  150.                     startY = (int) event.getY();  
  151.                 }  
  152.                 break;  
  153.   
  154.             case MotionEvent.ACTION_UP:  
  155.   
  156.                 if (state != REFRESHING && state != LOADING) {  
  157.                     if (state == DONE) {  
  158.                           
  159.                     }  
  160.                     if (state == PULL_To_REFRESH) {  
  161.                         state = DONE;  
  162.                         changeHeaderViewByState();  
  163.                     }  
  164.                     if (state == RELEASE_To_REFRESH) {  
  165.                         state = REFRESHING;  
  166.                         changeHeaderViewByState();  
  167.                         onRefresh();  
  168.                     }  
  169.                 }  
  170.   
  171.                 isRecored = false;  
  172.                 isBack = false;  
  173.   
  174.                 break;  
  175.   
  176.             case MotionEvent.ACTION_MOVE:  
  177.                 int tempY = (int) event.getY();  
  178.   
  179.                 if (!isRecored && firstItemIndex == 0) {  
  180.                     isRecored = true;  
  181.                     startY = tempY;  
  182.                 }  
  183.   
  184.                 if (state != REFRESHING && isRecored && state != LOADING) {  
  185.   
  186.                     // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动  
  187.                     // 可以松手去刷新了  
  188.                     if (state == RELEASE_To_REFRESH) {  
  189.   
  190.                         setSelection(0);  
  191.   
  192.                         // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步  
  193.                         if (((tempY - startY) / RATIO < headContentHeight) && (tempY - startY) > 0) {  
  194.                             state = PULL_To_REFRESH;  
  195.                             changeHeaderViewByState();  
  196.                         }  
  197.                         // 一下子推到顶了  
  198.                         else if (tempY - startY <= 0) {  
  199.                             state = DONE;  
  200.                             changeHeaderViewByState();  
  201.                         }  
  202.                         // 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步  
  203.                     }  
  204.                     // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态  
  205.                     if (state == PULL_To_REFRESH) {  
  206.   
  207.                         setSelection(0);  
  208.   
  209.                         // 下拉到可以进入RELEASE_TO_REFRESH的状态  
  210.                         if ((tempY - startY) / RATIO >= headContentHeight) {  
  211.                             state = RELEASE_To_REFRESH;  
  212.                             isBack = true;  
  213.                             changeHeaderViewByState();  
  214.                         }  
  215.                         else if (tempY - startY <= 0) {  
  216.                             state = DONE;  
  217.                             changeHeaderViewByState();  
  218.                         }  
  219.                     }  
  220.   
  221.                     if (state == DONE) {  
  222.                         if (tempY - startY > 0) {  
  223.                             state = PULL_To_REFRESH;  
  224.                             changeHeaderViewByState();  
  225.                         }  
  226.                     }  
  227.   
  228.                     if (state == PULL_To_REFRESH) {  
  229.                         headView.setPadding(0, -1 * headContentHeight + (tempY - startY) / RATIO, 00);  
  230.   
  231.                     }  
  232.   
  233.                     if (state == RELEASE_To_REFRESH) {  
  234.                         headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 00);  
  235.                     }  
  236.   
  237.                 }  
  238.   
  239.                 break;  
  240.             }  
  241.         }  
  242.   
  243.         return super.onTouchEvent(event);  
  244.     }  
  245.   
  246.     // 当状态改变时候,调用该方法,以更新界面  
  247.     private void changeHeaderViewByState() {  
  248.         switch (state) {  
  249.         case RELEASE_To_REFRESH:  
  250.             arrowImageView.setVisibility(View.VISIBLE);  
  251.             progressBar.setVisibility(View.GONE);  
  252.             tipsTextview.setVisibility(View.VISIBLE);  
  253.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  254.   
  255.             arrowImageView.clearAnimation();  
  256.             arrowImageView.startAnimation(animation);  
  257.             tipsTextview.setText("松开刷新");  
  258.   
  259.             break;  
  260.         case PULL_To_REFRESH:  
  261.             progressBar.setVisibility(View.GONE);  
  262.             tipsTextview.setVisibility(View.VISIBLE);  
  263.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  264.             arrowImageView.clearAnimation();  
  265.             arrowImageView.setVisibility(View.VISIBLE);  
  266.             // 是由RELEASE_To_REFRESH状态转变来的  
  267.             if (isBack) {  
  268.                 isBack = false;  
  269.                 arrowImageView.clearAnimation();  
  270.                 arrowImageView.startAnimation(reverseAnimation);  
  271.   
  272.                 tipsTextview.setText("下拉刷新");  
  273.             } else {  
  274.                 tipsTextview.setText("下拉刷新");  
  275.             }  
  276.             break;  
  277.   
  278.         case REFRESHING:  
  279.             headView.setPadding(0000);  
  280.             progressBar.setVisibility(View.VISIBLE);  
  281.             arrowImageView.clearAnimation();  
  282.             arrowImageView.setVisibility(View.GONE);  
  283.             tipsTextview.setText("正在刷新...");  
  284.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  285.   
  286.             break;  
  287.         case DONE:  
  288.             headView.setPadding(0, -1 * headContentHeight, 00);  
  289.   
  290.             progressBar.setVisibility(View.GONE);  
  291.             arrowImageView.clearAnimation();  
  292.             arrowImageView.setImageResource(R.drawable.arrow);  
  293.             tipsTextview.setText("下拉刷新");  
  294.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  295.   
  296.             break;  
  297.         }  
  298.     }  
  299.   
  300.     public void setonRefreshListener(OnRefreshListener refreshListener) {  
  301.         this.refreshListener = refreshListener;  
  302.         isRefreshable = true;  
  303.     }  
  304.       
  305.     public void setonLoadListener(OnLoadListener loadListener) {  
  306.         this.loadListener = loadListener;  
  307.     }  
  308.   
  309.     public interface OnRefreshListener {  
  310.         public void onRefresh();  
  311.     }  
  312.       
  313.     public interface OnLoadListener {  
  314.         public void onLoad();  
  315.     }  
  316.   
  317.     @SuppressWarnings("deprecation")  
  318.     public void onRefreshComplete() {  
  319.         state = DONE;  
  320.         lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());  
  321.         changeHeaderViewByState();  
  322.     }  
  323.       
  324.     private void onLoad() {  
  325.         if (loadListener != null) {  
  326.             moreProgressBar.setVisibility(View.VISIBLE);  
  327.             loadMoreView.setText(getContext().getString(R.string.load_more));  
  328.             loadListener.onLoad();  
  329.         }  
  330.     }  
  331.       
  332.     public void onLoadComplete() {  
  333. //      moreView.setVisibility(View.GONE);  
  334.         moreProgressBar.setVisibility(View.GONE);  
  335.         loadMoreView.setText(getContext().getString(R.string.more_data));  
  336.     }  
  337.   
  338.     private void onRefresh() {  
  339.         if (refreshListener != null) {  
  340.             refreshListener.onRefresh();  
  341.         }  
  342.     }  
  343.   
  344.     private void measureView(View child) {  
  345.         ViewGroup.LayoutParams p = child.getLayoutParams();  
  346.         if (p == null) {  
  347.             p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);  
  348.         }  
  349.         int childWidthSpec = ViewGroup.getChildMeasureSpec(00 + 0, p.width);  
  350.         int lpHeight = p.height;  
  351.         int childHeightSpec;  
  352.         if (lpHeight > 0) {  
  353.             childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);  
  354.         } else {  
  355.             childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);  
  356.         }  
  357.         child.measure(childWidthSpec, childHeightSpec);  
  358.     }  
  359.   
  360.     @SuppressWarnings("deprecation")  
  361.     public void setAdapter(BaseAdapter adapter) {  
  362.         lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());  
  363.         super.setAdapter(adapter);  
  364.     }  
  365.   
  366. }  


在 CustomListView 中有2个回调接口,OnRefreshListener 和 OnLoadListener ,分别对应 下拉和点击加载更多 时候的回调函数。在下拉刷新完成之后要调用 mListView.onRefreshComplete(); 来隐藏掉 头部,调用 mListView.onLoadComplete(); 隐藏掉 底部的加载view。


header.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- ListView的头部 -->  
  3.   
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="wrap_content" >  
  7.   
  8.     <!-- 内容 -->  
  9.   
  10.     <RelativeLayout  
  11.         android:id="@+id/head_contentLayout"  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:paddingLeft="30dp" >  
  15.   
  16.         <!-- 箭头图像、进度条 -->  
  17.   
  18.         <FrameLayout  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_alignParentLeft="true"  
  22.             android:layout_centerVertical="true" >  
  23.   
  24.             <!-- 箭头 -->  
  25.   
  26.             <ImageView  
  27.                 android:id="@+id/head_arrowImageView"  
  28.                 android:layout_width="wrap_content"  
  29.                 android:layout_height="wrap_content"  
  30.                 android:layout_gravity="center"  
  31.                 android:contentDescription="@string/app_name"  
  32.                 android:src="@drawable/arrow" />  
  33.   
  34.             <!-- 进度条 -->  
  35.   
  36.             <ProgressBar  
  37.                 android:id="@+id/head_progressBar"  
  38.                 style="?android:attr/progressBarStyleSmall"  
  39.                 android:layout_width="wrap_content"  
  40.                 android:layout_height="wrap_content"  
  41.                 android:layout_gravity="center"  
  42.                 android:indeterminateDrawable="@drawable/progressbar_bg"  
  43.                 android:visibility="gone" />  
  44.         </FrameLayout>  
  45.   
  46.         <!-- 提示、最近更新 -->  
  47.   
  48.         <LinearLayout  
  49.             android:layout_width="wrap_content"  
  50.             android:layout_height="wrap_content"  
  51.             android:layout_centerHorizontal="true"  
  52.             android:gravity="center_horizontal"  
  53.             android:orientation="vertical" >  
  54.   
  55.             <!-- 提示 -->  
  56.   
  57.             <TextView  
  58.                 android:id="@+id/head_tipsTextView"  
  59.                 android:layout_width="wrap_content"  
  60.                 android:layout_height="wrap_content"  
  61.                 android:text="@string/pull_to_refresh_pull_label"  
  62.                 android:textColor="@color/pull_refresh_textview"  
  63.                 android:textSize="20sp" />  
  64.   
  65.             <!-- 最近更新 -->  
  66.   
  67.             <TextView  
  68.                 android:id="@+id/head_lastUpdatedTextView"  
  69.                 android:layout_width="wrap_content"  
  70.                 android:layout_height="wrap_content"  
  71.                 android:text="@string/pull_to_refresh_refresh_lasttime"  
  72.                 android:textColor="@color/gold"  
  73.                 android:textSize="10sp" />  
  74.         </LinearLayout>  
  75.     </RelativeLayout>  
  76.   
  77. </LinearLayout>  



listfooter_more.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:gravity="center_horizontal"  
  6.     android:orientation="horizontal"  
  7.     android:padding="15dp"  
  8.      >  
  9.   
  10.     <ProgressBar  
  11.         android:id="@+id/pull_to_refresh_progress"  
  12.         style="@android:style/Widget.ProgressBar.Small.Inverse"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="wrap_content"  
  15.         android:gravity="center"  
  16.         android:indeterminate="true"  
  17.         android:visibility="gone" >  
  18.     </ProgressBar>  
  19.   
  20.     <TextView  
  21.         android:id="@+id/load_more"  
  22.         android:layout_width="wrap_content"  
  23.         android:layout_height="wrap_content"  
  24.         android:layout_marginLeft="10.0dp"  
  25.         android:gravity="center"  
  26.         android:text="@string/more_data"  
  27.         android:textColor="@color/black" >  
  28.     </TextView>  
  29.   
  30. </LinearLayout>  


MainActivity.java

  1. package com.example.uitest;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.graphics.BitmapFactory;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.util.Log;  
  12. import android.view.LayoutInflater;  
  13. import android.view.Menu;  
  14. import android.view.View;  
  15. import android.view.ViewGroup;  
  16. import android.widget.AdapterView;  
  17. import android.widget.AdapterView.OnItemClickListener;  
  18. import android.widget.BaseAdapter;  
  19. import android.widget.ImageView;  
  20. import android.widget.TextView;  
  21.   
  22. import com.example.uitest.model.AppInfo;  
  23. import com.example.uitest.view.CustomListView;  
  24. import com.example.uitest.view.CustomListView.OnLoadListener;  
  25. import com.example.uitest.view.CustomListView.OnRefreshListener;  
  26.   
  27. public class MainActivity extends Activity {  
  28.       
  29.     private static final String TAG = MainActivity.class.getSimpleName();  
  30.   
  31.     private static final int LOAD_DATA_FINISH = 10;  
  32.   
  33.     private static final int REFRESH_DATA_FINISH = 11;  
  34.       
  35.     private List<AppInfo> mList = new ArrayList<AppInfo>();  
  36.     private CustomListAdapter mAdapter;  
  37.     private CustomListView mListView;  
  38.     private int count = 10;  
  39.     private Handler handler = new Handler(){  
  40.         public void handleMessage(android.os.Message msg) {  
  41.             switch (msg.what) {  
  42.             case REFRESH_DATA_FINISH:  
  43.                   
  44.                 if(mAdapter!=null){  
  45.                     mAdapter.notifyDataSetChanged();  
  46.                 }  
  47.                 mListView.onRefreshComplete();  //下拉刷新完成  
  48.                 break;  
  49.             case LOAD_DATA_FINISH:  
  50.                 if(mAdapter!=null){  
  51.                     mAdapter.notifyDataSetChanged();  
  52.                 }  
  53.                 mListView.onLoadComplete(); //加载更多完成  
  54.                 break;  
  55.             default:  
  56.                 break;  
  57.             }  
  58.         };  
  59.     };  
  60.       
  61.     @Override  
  62.     protected void onCreate(Bundle savedInstanceState) {  
  63.         super.onCreate(savedInstanceState);  
  64.         setContentView(R.layout.activity_main);  
  65.           
  66.         buildAppData();  
  67.           
  68.         mAdapter = new CustomListAdapter(this);  
  69.         mListView = (CustomListView) findViewById(R.id.mListView);  
  70.         mListView.setAdapter(mAdapter);  
  71.           
  72.         mListView.setonRefreshListener(new OnRefreshListener() {  
  73.               
  74.             @Override  
  75.             public void onRefresh() {  
  76.                 //TODO 下拉刷新  
  77.                 Log.e(TAG, "onRefresh");  
  78.                 loadData(0);  
  79.             }  
  80.         });  
  81.           
  82.         mListView.setonLoadListener(new OnLoadListener() {  
  83.               
  84.             @Override  
  85.             public void onLoad() {  
  86.                 //TODO 加载更多  
  87.                 Log.e(TAG, "onLoad");  
  88.                 loadData(1);  
  89.             }  
  90.         });  
  91.           
  92.         mListView.setOnItemClickListener(new OnItemClickListener() {  
  93.   
  94.             @Override  
  95.             public void onItemClick(AdapterView<?> parent, View view,  
  96.                     int position, long id) {  
  97.   
  98.                 Log.e(TAG, "click position:" + position);  
  99.   
  100.             }  
  101.   
  102.         });  
  103.     }  
  104.       
  105.     public void loadData(final int type){  
  106.         new Thread(){  
  107.             @Override  
  108.             public void run() {  
  109.                   
  110.                 for(int i=count;i<count+10;i++){  
  111.                     AppInfo ai = new AppInfo();  
  112.   
  113.                     ai.setAppIcon(BitmapFactory.decodeResource(getResources(),  
  114.                             R.drawable.ic_launcher));  
  115.                     ai.setAppName("应用Demo_" + i);  
  116.                     ai.setAppVer("版本: " + (i % 10 + 1) + "." + (i % 8 + 2) + "."  
  117.                             + (i % 6 + 3));  
  118.                     ai.setAppSize("大小: " + i * 10 + "MB");  
  119.   
  120.                     mList.add(ai);  
  121.                 }  
  122.                 count += 10;  
  123.                   
  124.                 try {  
  125.                     Thread.sleep(300);  
  126.                 } catch (InterruptedException e) {  
  127.                     e.printStackTrace();  
  128.                 }  
  129.                   
  130.                 if(type==0){    //下拉刷新  
  131. //                  Collections.reverse(mList); //逆序  
  132.                     handler.sendEmptyMessage(REFRESH_DATA_FINISH);  
  133.                 }else if(type==1){  
  134.                     handler.sendEmptyMessage(LOAD_DATA_FINISH);  
  135.                 }  
  136.                   
  137.             }  
  138.         }.start();  
  139.     }  
  140.       
  141.     /** 
  142.      * 初始化应用数据 
  143.      */  
  144.     private void buildAppData() {  
  145.         for (int i = 0; i < 10; i++) {  
  146.             AppInfo ai = new AppInfo();  
  147.   
  148.             ai.setAppIcon(BitmapFactory.decodeResource(getResources(),  
  149.                     R.drawable.ic_launcher));  
  150.             ai.setAppName("应用Demo_" + i);  
  151.             ai.setAppVer("版本: " + (i % 10 + 1) + "." + (i % 8 + 2) + "."  
  152.                     + (i % 6 + 3));  
  153.             ai.setAppSize("大小: " + i * 10 + "MB");  
  154.   
  155.             mList.add(ai);  
  156.         }  
  157.     }  
  158.   
  159.     @Override  
  160.     public boolean onCreateOptionsMenu(Menu menu) {  
  161.         // Inflate the menu; this adds items to the action bar if it is present.  
  162.         getMenuInflater().inflate(R.menu.main, menu);  
  163.         return true;  
  164.     }  
  165.       
  166.     public class CustomListAdapter extends BaseAdapter {  
  167.   
  168.         private LayoutInflater mInflater;  
  169.   
  170.         public CustomListAdapter(Context context) {  
  171.             mInflater = LayoutInflater.from(context);  
  172.         }  
  173.   
  174.         @Override  
  175.         public int getCount() {  
  176.             return mList.size();  
  177.         }  
  178.   
  179.         @Override  
  180.         public Object getItem(int arg0) {  
  181.             return mList.get(arg0);  
  182.         }  
  183.   
  184.         @Override  
  185.         public long getItemId(int position) {  
  186.             return position;  
  187.         }  
  188.   
  189.         @Override  
  190.         public View getView(int position, View convertView, ViewGroup parent) {  
  191.             if (getCount() == 0) {  
  192.                 return null;  
  193.             }  
  194.   
  195.             ViewHolder holder = null;  
  196.             if (convertView == null) {  
  197.                 convertView = mInflater.inflate(R.layout.list_item, null);  
  198.   
  199.                 holder = new ViewHolder();  
  200.                 holder.ivImage = (ImageView) convertView  
  201.                         .findViewById(R.id.ivIcon);  
  202.                 holder.tvName = (TextView) convertView  
  203.                         .findViewById(R.id.tvName);  
  204.                 holder.tvVer = (TextView) convertView.findViewById(R.id.tvVer);  
  205.                 holder.tvSize = (TextView) convertView  
  206.                         .findViewById(R.id.tvSize);  
  207.                 convertView.setTag(holder);  
  208.             } else {  
  209.                 holder = (ViewHolder) convertView.getTag();  
  210.             }  
  211.   
  212.             AppInfo ai = mList.get(position);  
  213.             holder.ivImage.setImageBitmap(ai.getAppIcon());  
  214.             holder.tvName.setText(ai.getAppName());  
  215.             holder.tvVer.setText(ai.getAppVer());  
  216.             holder.tvSize.setText(ai.getAppSize());  
  217.   
  218.             return convertView;  
  219.         }  
  220.     }  
  221.   
  222.     public static class ViewHolder {  
  223.         private ImageView ivImage;  
  224.         private TextView tvName;  
  225.         private TextView tvVer;  
  226.         private TextView tvSize;  
  227.   
  228.     }  
  229. }  


list_item.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout   
  3.     xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="wrap_content" >  
  6.   
  7.     <ImageView  
  8.         android:id="@+id/ivIcon"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:contentDescription="@string/image_desc"  
  12.         android:src="@drawable/ic_launcher" />  
  13.   
  14.     <LinearLayout  
  15.         android:id="@+id/appInfo"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_marginLeft="5dip"  
  19.         android:layout_toRightOf="@id/ivIcon"  
  20.         android:orientation="vertical" >  
  21.   
  22.         <TextView  
  23.             android:id="@+id/tvName"  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:text="@string/name"  
  27.             android:textColor="#000000"  
  28.             android:textSize="16sp" />  
  29.   
  30.         <TextView  
  31.             android:id="@+id/tvVer"  
  32.             android:layout_width="wrap_content"  
  33.             android:layout_height="wrap_content"  
  34.             android:text="@string/ver"  
  35.             android:textColor="#666666"  
  36.             android:textSize="13sp" />  
  37.   
  38.         <TextView  
  39.             android:id="@+id/tvSize"  
  40.             android:layout_width="wrap_content"  
  41.             android:layout_height="wrap_content"  
  42.             android:text="@string/size"  
  43.             android:textColor="#666666"  
  44.             android:textSize="13sp" />  
  45.     </LinearLayout>  
  46.   
  47.     <Button  
  48.         android:id="@+id/btnClick"  
  49.         android:layout_width="80dip"  
  50.         android:layout_height="wrap_content"  
  51.         android:layout_alignParentRight="true"  
  52.         android:layout_centerVertical="true"  
  53.         android:focusable="false"  
  54.         android:text="@string/mgr"  
  55.         android:textColor="#000000"  
  56.         android:textSize="16sp" />  
  57.   
  58. </RelativeLayout>  



工程下载地址:http://download.csdn.net/detail/fx_sky/5646017



目录
相关文章
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
38 0
|
4月前
|
XML 物联网 API
Android Ble蓝牙App(五)数据操作
Android Ble蓝牙App(五)数据操作
|
4月前
|
数据库 Android开发 开发者
Android Studio入门之内容共享ContentProvider讲解以及实现共享数据实战(附源码 超详细必看)
Android Studio入门之内容共享ContentProvider讲解以及实现共享数据实战(附源码 超详细必看)
36 0
|
3天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
3 0
|
3天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
5 0
|
17天前
|
XML Java Android开发
Android每点击一次按钮就添加一条数据
Android每点击一次按钮就添加一条数据
21 1
|
1月前
|
存储 Android开发 C++
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
30 3
|
6月前
|
存储 安全 Java
Android DataStore:安全存储和轻松管理数据
Android DataStore:安全存储和轻松管理数据
|
2月前
|
JavaScript Java 数据安全/隐私保护
安卓逆向 -- POST数据解密
安卓逆向 -- POST数据解密
25 2