Listview下拉刷新上拉加载更多

来源:互联网 发布:研发生产销售 知乎 编辑:程序博客网 时间:2024/04/24 18:00

Android中ListView下拉刷新、上拉载入更多示例一文中,Maxwin兄给出的控件比较强大,前面有详细介绍,但是有个不足就是,里面使用了一些资源文件,包括图片,String,layout,这样不利于封装打包,下面我将源码进行改进,所有布局全部用代码实现,这样直接将src和assets打包成jar就成了一个非常方便以后使用的扩展ListView控件,代码如下:

XListView:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @file XListView.java 
  3.  * @package me.maxwin.view 
  4.  * @create Mar 18, 2012 6:28:41 PM 
  5.  * @author Maxwin 
  6.  * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. 
  7.  *      Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). 
  8.  */  
  9. package com.home.view;  
  10.   
  11. import android.content.Context;  
  12. import android.util.AttributeSet;  
  13. import android.view.MotionEvent;  
  14. import android.view.View;  
  15. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
  16. import android.view.animation.DecelerateInterpolator;  
  17. import android.widget.AbsListView;  
  18. import android.widget.AbsListView.OnScrollListener;  
  19. import android.widget.ListAdapter;  
  20. import android.widget.ListView;  
  21. import android.widget.RelativeLayout;  
  22. import android.widget.Scroller;  
  23. import android.widget.TextView;  
  24.   
  25. public class XListView extends ListView implements OnScrollListener {  
  26.   
  27.     private float mLastY = -1// save event y  
  28.     private Scroller mScroller; // used for scroll back  
  29.     private OnScrollListener mScrollListener; // user's scroll listener  
  30.   
  31.     // the interface to trigger refresh and load more.  
  32.     private IXListViewListener mListViewListener;  
  33.   
  34.     // -- header view  
  35.     private XListViewHeader mHeaderView;  
  36.     // header view content, use it to calculate the Header's height. And hide it  
  37.     // when disable pull refresh.  
  38.     private RelativeLayout mHeaderViewContent;  
  39.     private TextView mHeaderTimeView;  
  40.     private int mHeaderViewHeight; // header view's height  
  41.     private boolean mEnablePullRefresh = true;  
  42.     private boolean mPullRefreshing = false// is refreashing.  
  43.   
  44.     // -- footer view  
  45.     private XListViewFooter mFooterView;  
  46.     private boolean mEnablePullLoad;  
  47.     private boolean mPullLoading;  
  48.     private boolean mIsFooterReady = false;  
  49.   
  50.     // total list items, used to detect is at the bottom of listview.  
  51.     private int mTotalItemCount;  
  52.   
  53.     // for mScroller, scroll back from header or footer.  
  54.     private int mScrollBack;  
  55.     private final static int SCROLLBACK_HEADER = 0;  
  56.     private final static int SCROLLBACK_FOOTER = 1;  
  57.   
  58.     private final static int SCROLL_DURATION = 400// scroll back duration  
  59.     private final static int PULL_LOAD_MORE_DELTA = 50// when pull up >= 50px  
  60.                                                         // at bottom, trigger  
  61.                                                         // load more.  
  62.     private final static float OFFSET_RADIO = 1.8f; // support iOS like pull  
  63.                                                     // feature.  
  64.   
  65.     /** 
  66.      * @param context 
  67.      */  
  68.     public XListView(Context context) {  
  69.         super(context);  
  70.         initWithContext(context);  
  71.     }  
  72.   
  73.     public XListView(Context context, AttributeSet attrs) {  
  74.         super(context, attrs);  
  75.         initWithContext(context);  
  76.     }  
  77.   
  78.     public XListView(Context context, AttributeSet attrs, int defStyle) {  
  79.         super(context, attrs, defStyle);  
  80.         initWithContext(context);  
  81.     }  
  82.   
  83.     private void initWithContext(Context context) {  
  84.         mScroller = new Scroller(context, new DecelerateInterpolator());  
  85.         // XListView need the scroll event, and it will dispatch the event to  
  86.         // user's listener (as a proxy).  
  87.         super.setOnScrollListener(this);  
  88.   
  89.         // init header view  
  90.         mHeaderView = new XListViewHeader(context);  
  91.         mHeaderViewContent = (RelativeLayout) mHeaderView  
  92.                 .findViewById(XListViewHeader.RELAYOUT_ID);  
  93.         mHeaderTimeView = (TextView) mHeaderView  
  94.                 .findViewById(XListViewHeader.HEAD_TIME_VIEW_ID);  
  95.         addHeaderView(mHeaderView);  
  96.   
  97.         // init footer view  
  98.         mFooterView = new XListViewFooter(context);  
  99.   
  100.         // init header height  
  101.         mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(  
  102.                 new OnGlobalLayoutListener() {  
  103.                     @Override  
  104.                     public void onGlobalLayout() {  
  105.                         mHeaderViewHeight = mHeaderViewContent.getHeight();  
  106.                         getViewTreeObserver()  
  107.                                 .removeGlobalOnLayoutListener(this);  
  108.                     }  
  109.                 });  
  110.     }  
  111.   
  112.     @Override  
  113.     public void setAdapter(ListAdapter adapter) {  
  114.         // make sure XListViewFooter is the last footer view, and only add once.  
  115.         if (mIsFooterReady == false) {  
  116.             mIsFooterReady = true;  
  117.             addFooterView(mFooterView);  
  118.         }  
  119.         super.setAdapter(adapter);  
  120.     }  
  121.   
  122.     /** 
  123.      * enable or disable pull down refresh feature. 
  124.      *  
  125.      * @param enable 
  126.      */  
  127.     public void setPullRefreshEnable(boolean enable) {  
  128.         mEnablePullRefresh = enable;  
  129.         if (!mEnablePullRefresh) { // disable, hide the content  
  130.             mHeaderViewContent.setVisibility(View.INVISIBLE);  
  131.         } else {  
  132.             mHeaderViewContent.setVisibility(View.VISIBLE);  
  133.         }  
  134.     }  
  135.   
  136.     /** 
  137.      * enable or disable pull up load more feature. 
  138.      *  
  139.      * @param enable 
  140.      */  
  141.     public void setPullLoadEnable(boolean enable) {  
  142.         mEnablePullLoad = enable;  
  143.         if (!mEnablePullLoad) {  
  144.             mFooterView.hide();  
  145.             mFooterView.setOnClickListener(null);  
  146.         } else {  
  147.             mPullLoading = false;  
  148.             mFooterView.show();  
  149.             mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  150.             // both "pull up" and "click" will invoke load more.  
  151.             mFooterView.setOnClickListener(new OnClickListener() {  
  152.                 @Override  
  153.                 public void onClick(View v) {  
  154.                     startLoadMore();  
  155.                 }  
  156.             });  
  157.         }  
  158.     }  
  159.   
  160.     /** 
  161.      * stop refresh, reset header view. 
  162.      */  
  163.     public void stopRefresh() {  
  164.         if (mPullRefreshing == true) {  
  165.             mPullRefreshing = false;  
  166.             resetHeaderHeight();  
  167.         }  
  168.     }  
  169.   
  170.     /** 
  171.      * stop load more, reset footer view. 
  172.      */  
  173.     public void stopLoadMore() {  
  174.         if (mPullLoading == true) {  
  175.             mPullLoading = false;  
  176.             mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  177.         }  
  178.     }  
  179.   
  180.     /** 
  181.      * set last refresh time 
  182.      *  
  183.      * @param time 
  184.      */  
  185.     public void setRefreshTime(String time) {  
  186.         mHeaderTimeView.setText(time);  
  187.     }  
  188.   
  189.     private void invokeOnScrolling() {  
  190.         if (mScrollListener instanceof OnXScrollListener) {  
  191.             OnXScrollListener l = (OnXScrollListener) mScrollListener;  
  192.             l.onXScrolling(this);  
  193.         }  
  194.     }  
  195.   
  196.     private void updateHeaderHeight(float delta) {  
  197.         mHeaderView.setVisiableHeight((int) delta  
  198.                 + mHeaderView.getVisiableHeight());  
  199.         if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头  
  200.             if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {  
  201.                 mHeaderView.setState(XListViewHeader.STATE_READY);  
  202.             } else {  
  203.                 mHeaderView.setState(XListViewHeader.STATE_NORMAL);  
  204.             }  
  205.         }  
  206.         setSelection(0); // scroll to top each time  
  207.     }  
  208.   
  209.     /** 
  210.      * reset header view's height. 
  211.      */  
  212.     private void resetHeaderHeight() {  
  213.         int height = mHeaderView.getVisiableHeight();  
  214.         if (height == 0// not visible.  
  215.             return;  
  216.         // refreshing and header isn't shown fully. do nothing.  
  217.         if (mPullRefreshing && height <= mHeaderViewHeight) {  
  218.             return;  
  219.         }  
  220.         int finalHeight = 0// default: scroll back to dismiss header.  
  221.         // is refreshing, just scroll back to show all the header.  
  222.         if (mPullRefreshing && height > mHeaderViewHeight) {  
  223.             finalHeight = mHeaderViewHeight;  
  224.         }  
  225.         mScrollBack = SCROLLBACK_HEADER;  
  226.         mScroller.startScroll(0, height, 0, finalHeight - height,  
  227.                 SCROLL_DURATION);  
  228.         // trigger computeScroll  
  229.         invalidate();  
  230.     }  
  231.   
  232.     private void updateFooterHeight(float delta) {  
  233.         int height = mFooterView.getBottomMargin() + (int) delta;  
  234.         if (mEnablePullLoad && !mPullLoading) {  
  235.             if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load  
  236.                                                     // more.  
  237.                 mFooterView.setState(XListViewFooter.STATE_READY);  
  238.             } else {  
  239.                 mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  240.             }  
  241.         }  
  242.         mFooterView.setBottomMargin(height);  
  243.   
  244.         // setSelection(mTotalItemCount - 1); // scroll to bottom  
  245.     }  
  246.   
  247.     private void resetFooterHeight() {  
  248.         int bottomMargin = mFooterView.getBottomMargin();  
  249.         if (bottomMargin > 0) {  
  250.             mScrollBack = SCROLLBACK_FOOTER;  
  251.             mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,  
  252.                     SCROLL_DURATION);  
  253.             invalidate();  
  254.         }  
  255.     }  
  256.   
  257.     private void startLoadMore() {  
  258.         mPullLoading = true;  
  259.         mFooterView.setState(XListViewFooter.STATE_LOADING);  
  260.         if (mListViewListener != null) {  
  261.             mListViewListener.onLoadMore();  
  262.         }  
  263.     }  
  264.   
  265.     @Override  
  266.     public boolean onTouchEvent(MotionEvent ev) {  
  267.         if (mLastY == -1) {  
  268.             mLastY = ev.getRawY();  
  269.         }  
  270.   
  271.         switch (ev.getAction()) {  
  272.         case MotionEvent.ACTION_DOWN:  
  273.             mLastY = ev.getRawY();  
  274.             break;  
  275.         case MotionEvent.ACTION_MOVE:  
  276.             final float deltaY = ev.getRawY() - mLastY;  
  277.             mLastY = ev.getRawY();  
  278.             System.out.println("数据监测:" + getFirstVisiblePosition() + "---->"  
  279.                     + getLastVisiblePosition());  
  280.             if (getFirstVisiblePosition() == 0  
  281.                     && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {  
  282.                 // the first item is showing, header has shown or pull down.  
  283.                 updateHeaderHeight(deltaY / OFFSET_RADIO);  
  284.                 invokeOnScrolling();  
  285.             } else if (getLastVisiblePosition() == mTotalItemCount - 1  
  286.                     && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {  
  287.                 // last item, already pulled up or want to pull up.  
  288.                 updateFooterHeight(-deltaY / OFFSET_RADIO);  
  289.             }  
  290.             break;  
  291.         default:  
  292.             mLastY = -1// reset  
  293.             if (getFirstVisiblePosition() == 0) {  
  294.                 // invoke refresh  
  295.                 if (mEnablePullRefresh  
  296.                         && mHeaderView.getVisiableHeight() > mHeaderViewHeight) {  
  297.                     mPullRefreshing = true;  
  298.                     mHeaderView.setState(XListViewHeader.STATE_REFRESHING);  
  299.                     if (mListViewListener != null) {  
  300.                         mListViewListener.onRefresh();  
  301.                     }  
  302.                 }  
  303.                 resetHeaderHeight();  
  304.             }  
  305.             if (getLastVisiblePosition() == mTotalItemCount - 1) {  
  306.                 // invoke load more.  
  307.                 if (mEnablePullLoad  
  308.                         && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {  
  309.                     startLoadMore();  
  310.                 }  
  311.                 resetFooterHeight();  
  312.             }  
  313.             break;  
  314.         }  
  315.         return super.onTouchEvent(ev);  
  316.     }  
  317.   
  318.     @Override  
  319.     public void computeScroll() {  
  320.         if (mScroller.computeScrollOffset()) {  
  321.             if (mScrollBack == SCROLLBACK_HEADER) {  
  322.                 mHeaderView.setVisiableHeight(mScroller.getCurrY());  
  323.             } else {  
  324.                 mFooterView.setBottomMargin(mScroller.getCurrY());  
  325.             }  
  326.             postInvalidate();  
  327.             invokeOnScrolling();  
  328.         }  
  329.         super.computeScroll();  
  330.     }  
  331.   
  332.     @Override  
  333.     public void setOnScrollListener(OnScrollListener l) {  
  334.         mScrollListener = l;  
  335.     }  
  336.   
  337.     @Override  
  338.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  339.         if (mScrollListener != null) {  
  340.             mScrollListener.onScrollStateChanged(view, scrollState);  
  341.         }  
  342.     }  
  343.   
  344.     @Override  
  345.     public void onScroll(AbsListView view, int firstVisibleItem,  
  346.             int visibleItemCount, int totalItemCount) {  
  347.         // send to user's listener  
  348.         mTotalItemCount = totalItemCount;  
  349.         if (mScrollListener != null) {  
  350.             mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,  
  351.                     totalItemCount);  
  352.         }  
  353.     }  
  354.   
  355.     public void setXListViewListener(IXListViewListener l) {  
  356.         mListViewListener = l;  
  357.     }  
  358.   
  359.     /** 
  360.      * you can listen ListView.OnScrollListener or this one. it will invoke 
  361.      * onXScrolling when header/footer scroll back. 
  362.      */  
  363.     public interface OnXScrollListener extends OnScrollListener {  
  364.         public void onXScrolling(View view);  
  365.     }  
  366.   
  367.     /** 
  368.      * implements this interface to get refresh/load more event. 
  369.      */  
  370.     public interface IXListViewListener {  
  371.         public void onRefresh();  
  372.   
  373.         public void onLoadMore();  
  374.     }  
  375. }  

XListViewFooter:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package com.home.view;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.view.Gravity;  
  6. import android.view.View;  
  7. import android.widget.LinearLayout;  
  8. import android.widget.ProgressBar;  
  9. import android.widget.RelativeLayout;  
  10. import android.widget.TextView;  
  11.   
  12. public class XListViewFooter extends LinearLayout {  
  13.     public final static int STATE_NORMAL = 0;  
  14.     public final static int STATE_READY = 1;  
  15.     public final static int STATE_LOADING = 2;  
  16.   
  17.     private Context mContext;  
  18.   
  19.     private RelativeLayout mContentView;  
  20.     private ProgressBar mProgressBar;  
  21.     private TextView mHintView;  
  22.   
  23.     public XListViewFooter(Context context) {  
  24.         super(context);  
  25.         initView(context);  
  26.     }  
  27.   
  28.     public XListViewFooter(Context context, AttributeSet attrs) {  
  29.         super(context, attrs);  
  30.         initView(context);  
  31.     }  
  32.   
  33.     public void setState(int state) {  
  34.         mHintView.setVisibility(View.INVISIBLE);  
  35.         mProgressBar.setVisibility(View.INVISIBLE);  
  36.         mHintView.setVisibility(View.INVISIBLE);  
  37.         if (state == STATE_READY) {  
  38.             mHintView.setVisibility(View.VISIBLE);  
  39.             mHintView.setText("松开载入更多");  
  40.         } else if (state == STATE_LOADING) {  
  41.             mProgressBar.setVisibility(View.VISIBLE);  
  42.         } else {  
  43.             mHintView.setVisibility(View.VISIBLE);  
  44.             mHintView.setText("查看更多");  
  45.         }  
  46.     }  
  47.   
  48.     public void setBottomMargin(int height) {  
  49.         if (height < 0)  
  50.             return;  
  51.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  52.                 .getLayoutParams();  
  53.         lp.bottomMargin = height;  
  54.         mContentView.setLayoutParams(lp);  
  55.     }  
  56.   
  57.     public int getBottomMargin() {  
  58.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  59.                 .getLayoutParams();  
  60.         return lp.bottomMargin;  
  61.     }  
  62.   
  63.     /** 
  64.      * normal status 
  65.      */  
  66.     public void normal() {  
  67.         mHintView.setVisibility(View.VISIBLE);  
  68.         mProgressBar.setVisibility(View.GONE);  
  69.     }  
  70.   
  71.     /** 
  72.      * loading status 
  73.      */  
  74.     public void loading() {  
  75.         mHintView.setVisibility(View.GONE);  
  76.         mProgressBar.setVisibility(View.VISIBLE);  
  77.     }  
  78.   
  79.     /** 
  80.      * hide footer when disable pull load more 
  81.      */  
  82.     public void hide() {  
  83.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  84.                 .getLayoutParams();  
  85.         lp.height = 0;  
  86.         mContentView.setLayoutParams(lp);  
  87.     }  
  88.   
  89.     /** 
  90.      * show footer 
  91.      */  
  92.     public void show() {  
  93.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  94.                 .getLayoutParams();  
  95.         lp.height = LayoutParams.WRAP_CONTENT;  
  96.         mContentView.setLayoutParams(lp);  
  97.     }  
  98.   
  99.     private void initView(Context context) {  
  100.         mContext = context;  
  101.         // 根布局  
  102.         LinearLayout moreView = new LinearLayout(mContext);  
  103.         moreView.setLayoutParams(new LinearLayout.LayoutParams(  
  104.                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));  
  105.         // 将根布局加到该LinearLayout中  
  106.         addView(moreView);  
  107.   
  108.         // 根布局里面的相对布局  
  109.         mContentView = new RelativeLayout(mContext);  
  110.         LinearLayout.LayoutParams linearLp1 = new LinearLayout.LayoutParams(  
  111.                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);  
  112.         mContentView.setPadding(10101010);  
  113.         // 将相对布局relayout加到moreView根布局中  
  114.         moreView.addView(mContentView, linearLp1);  
  115.   
  116.         // 进度条mProgressBar  
  117.         mProgressBar = new ProgressBar(mContext);  
  118.         RelativeLayout.LayoutParams relativeLp1 = new RelativeLayout.LayoutParams(  
  119.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  120.         relativeLp1.addRule(RelativeLayout.CENTER_IN_PARENT);  
  121.         mProgressBar.setVisibility(View.INVISIBLE);  
  122.         // 将mProgressBar加入相对布局relayout中  
  123.         mContentView.addView(mProgressBar, relativeLp1);  
  124.   
  125.         // 查看更多的TextView  
  126.         mHintView = new TextView(mContext);  
  127.         mHintView.setText("查看更多");  
  128.         mHintView.setGravity(Gravity.CENTER);  
  129.         RelativeLayout.LayoutParams relativeLp2 = new RelativeLayout.LayoutParams(  
  130.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  131.         relativeLp2.addRule(RelativeLayout.CENTER_IN_PARENT);  
  132.         // 将其加入相对布局relayout中  
  133.         mContentView.addView(mHintView, relativeLp2);  
  134.     }  
  135.   
  136. }  

XListViewHeader:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package com.home.view;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5.   
  6. import android.content.Context;  
  7. import android.content.res.AssetManager;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.BitmapFactory;  
  10. import android.util.AttributeSet;  
  11. import android.view.Gravity;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.view.animation.Animation;  
  15. import android.view.animation.RotateAnimation;  
  16. import android.widget.ImageView;  
  17. import android.widget.LinearLayout;  
  18. import android.widget.ProgressBar;  
  19. import android.widget.RelativeLayout;  
  20. import android.widget.TextView;  
  21.   
  22. public class XListViewHeader extends LinearLayout {  
  23.     private LinearLayout mContainer;  
  24.     private ImageView mArrowImageView;  
  25.     private ProgressBar mProgressBar;  
  26.     private TextView mHintTextView;  
  27.     private int mState = STATE_NORMAL;  
  28.   
  29.     private Animation mRotateUpAnim;  
  30.     private Animation mRotateDownAnim;  
  31.   
  32.     private final int ROTATE_ANIM_DURATION = 180;  
  33.   
  34.     public final static int STATE_NORMAL = 0;  
  35.     public final static int STATE_READY = 1;  
  36.     public final static int STATE_REFRESHING = 2;  
  37.     public static final int LINEAROUT_1_ID = 1;  
  38.     public static final int RELAYOUT_ID = 2;  
  39.     public static final int HEAD_TIME_VIEW_ID = 3;  
  40.   
  41.     public XListViewHeader(Context context) {  
  42.         super(context);  
  43.         initView(context);  
  44.     }  
  45.   
  46.     /** 
  47.      * @param context 
  48.      * @param attrs 
  49.      */  
  50.     public XListViewHeader(Context context, AttributeSet attrs) {  
  51.         super(context, attrs);  
  52.         initView(context);  
  53.     }  
  54.   
  55.     private void initView(Context context) {  
  56.         // 根布局  
  57.         mContainer = new LinearLayout(context);  
  58.         mContainer.setGravity(Gravity.BOTTOM);  
  59.         // 初始情况,设置下拉刷新view高度为0  
  60.         LinearLayout.LayoutParams linearLp1 = new LinearLayout.LayoutParams(  
  61.                 LayoutParams.MATCH_PARENT, 0);  
  62.         // 将根布局加入该LinearLayout中  
  63.         addView(mContainer, linearLp1);  
  64.         setGravity(Gravity.BOTTOM);  
  65.   
  66.         // 里面的相对布局  
  67.         RelativeLayout relayout = new RelativeLayout(context);  
  68.         relayout.setId(RELAYOUT_ID);  
  69.         LinearLayout.LayoutParams linearLp2 = new LinearLayout.LayoutParams(  
  70.                 LayoutParams.MATCH_PARENT, 60);  
  71.         // 将里面的相对布局加入根布局中  
  72.         mContainer.addView(relayout, linearLp2);  
  73.   
  74.         // 相对布局里的子线性布局1  
  75.         LinearLayout linear1 = new LinearLayout(context);  
  76.         linear1.setId(LINEAROUT_1_ID);  
  77.         RelativeLayout.LayoutParams relativeLp1 = new RelativeLayout.LayoutParams(  
  78.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  79.         relativeLp1.addRule(RelativeLayout.CENTER_IN_PARENT);  
  80.         linear1.setGravity(Gravity.CENTER);  
  81.         linear1.setOrientation(LinearLayout.VERTICAL);  
  82.         // 将子布局linear1加入relayout中  
  83.         relayout.addView(linear1, relativeLp1);  
  84.   
  85.         // 下拉刷新提示TextView  
  86.         mHintTextView = new TextView(context);  
  87.         mHintTextView.setText("下拉刷新");  
  88.         LinearLayout.LayoutParams linearLp3 = new LinearLayout.LayoutParams(  
  89.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  90.         // 将TextView加入linear1中  
  91.         linear1.addView(mHintTextView, linearLp3);  
  92.   
  93.         // 子线性布局1(linear1)里的线性布局linear12  
  94.         LinearLayout linear12 = new LinearLayout(context);  
  95.         LinearLayout.LayoutParams linearLp4 = new LinearLayout.LayoutParams(  
  96.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  97.         linearLp4.setMargins(0300);  
  98.         // 将linear12加入linear1中  
  99.         linear1.addView(linear12, linearLp4);  
  100.   
  101.         // 提示时间TextView  
  102.         TextView tv = new TextView(context);  
  103.         tv.setText("上次更新时间:");  
  104.         tv.setTextSize(12);  
  105.         // 将提示时间TextView加入linear12  
  106.         linear12.addView(tv, linearLp3);  
  107.   
  108.         // 时间值TextView  
  109.         TextView tv2 = new TextView(context);  
  110.         tv2.setId(HEAD_TIME_VIEW_ID);  
  111.         tv2.setTextSize(12);  
  112.         // 将时间值TextView加入linear12  
  113.         linear12.addView(tv2, linearLp3);  
  114.   
  115.         // ImageView  
  116.         mArrowImageView = new ImageView(context);  
  117.         RelativeLayout.LayoutParams relativeLp2 = new RelativeLayout.LayoutParams(  
  118.                 ViewGroup.LayoutParams.WRAP_CONTENT,  
  119.                 ViewGroup.LayoutParams.WRAP_CONTENT);  
  120.         relativeLp2.rightMargin = 20;  
  121.         relativeLp2.addRule(RelativeLayout.CENTER_VERTICAL);  
  122.         relativeLp2.addRule(RelativeLayout.LEFT_OF, LINEAROUT_1_ID);  
  123.         mArrowImageView.setImageBitmap(readAssetImage(context));  
  124.         // 将ImageView加到相对布局relayout中  
  125.         relayout.addView(mArrowImageView, relativeLp2);  
  126.   
  127.         // ProgressBar  
  128.         mProgressBar = new ProgressBar(context);  
  129.         RelativeLayout.LayoutParams relativeLp3 = new RelativeLayout.LayoutParams(  
  130.                 4545);  
  131.         relativeLp3.addRule(RelativeLayout.LEFT_OF, LINEAROUT_1_ID);  
  132.         relativeLp3.addRule(RelativeLayout.CENTER_VERTICAL);  
  133.         relativeLp3.rightMargin = 20;  
  134.         mProgressBar.setVisibility(View.INVISIBLE);  
  135.         // 将mProgressBar加到相对布局relayout中  
  136.         relayout.addView(mProgressBar, relativeLp3);  
  137.   
  138.         mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,  
  139.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  140.                 0.5f);  
  141.         mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);  
  142.         mRotateUpAnim.setFillAfter(true);  
  143.         mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,  
  144.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  145.                 0.5f);  
  146.         mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);  
  147.         mRotateDownAnim.setFillAfter(true);  
  148.     }  
  149.   
  150.     public void setState(int state) {  
  151.         if (state == mState)  
  152.             return;  
  153.         if (state == STATE_REFRESHING) { // 显示进度  
  154.             mArrowImageView.clearAnimation();  
  155.             mArrowImageView.setVisibility(View.INVISIBLE);  
  156.             mProgressBar.setVisibility(View.VISIBLE);  
  157.         } else { // 显示箭头图片  
  158.             mArrowImageView.setVisibility(View.VISIBLE);  
  159.             mProgressBar.setVisibility(View.INVISIBLE);  
  160.         }  
  161.         switch (state) {  
  162.         case STATE_NORMAL:  
  163.             if (mState == STATE_READY) {  
  164.                 mArrowImageView.startAnimation(mRotateDownAnim);  
  165.             }  
  166.             if (mState == STATE_REFRESHING) {  
  167.                 mArrowImageView.clearAnimation();  
  168.             }  
  169.             mHintTextView.setText("下拉刷新");  
  170.             break;  
  171.         case STATE_READY:  
  172.             if (mState != STATE_READY) {  
  173.                 mArrowImageView.clearAnimation();  
  174.                 mArrowImageView.startAnimation(mRotateUpAnim);  
  175.                 mHintTextView.setText("松开刷新数据");  
  176.             }  
  177.             break;  
  178.         case STATE_REFRESHING:  
  179.             mHintTextView.setText("正在加载...");  
  180.             break;  
  181.         default:  
  182.         }  
  183.         mState = state;  
  184.     }  
  185.   
  186.     public void setVisiableHeight(int height) {  
  187.         if (height < 0)  
  188.             height = 0;  
  189.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContainer  
  190.                 .getLayoutParams();  
  191.         lp.height = height;  
  192.         mContainer.setLayoutParams(lp);  
  193.     }  
  194.   
  195.     public int getVisiableHeight() {  
  196.         return mContainer.getHeight();  
  197.     }  
  198.   
  199.     /** 
  200.      * 读取assets里面文件名为xlistview_arrow.png的图片 
  201.      *  
  202.      * @param context 
  203.      * @return bitmap 
  204.      */  
  205.     private Bitmap readAssetImage(Context context) {  
  206.         AssetManager asset = context.getAssets();  
  207.         InputStream assetFile = null;  
  208.         Bitmap bitmap = null;  
  209.         try {  
  210.             assetFile = asset.open("xlistview_arrow.png");  
  211.             bitmap = BitmapFactory.decodeStream(assetFile);  
  212.         } catch (IOException e) {  
  213.             e.printStackTrace();  
  214.         }  
  215.         return bitmap;  
  216.     }  
  217.   
  218. }  

然后将使用到的那张图片放在assets目录下和src一起打包即可。



0 0
原创粉丝点击