自定义上拉加载下拉刷新控件,从而实现滑动到底部时上拉加载更多的功能

/**
 * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
 */
public class RefreshLayout extends SwipeRefreshLayout implements
      OnScrollListener {

   /**
    * 滑动到最下面时的上拉操作
    */

   private int mTouchSlop;
   /**
    * listview实例
    */
   private ListView mListView;

   /**
    * 上拉监听器, 到了最底部的上拉加载操作
    */
   private OnLoadListener mOnLoadListener;

   /**
    * ListView的加载中footer
    */
   private View mListViewFooter;

   /**
    * 按下时的y坐标
    */
   private int mYDown;
   /**
    * 抬起时的y坐标, mYDown一起用于滑动到底部时判断是上拉还是下拉
    */
   private int mLastY;
   /**
    * 是否在加载中 ( 上拉加载更多 )
    */
   private boolean isLoading = false;

   /**
    * @param context
    */
   public RefreshLayout(Context context) {
      this(context, null);
   }

   @SuppressLint("InflateParams")
   public RefreshLayout(Context context, AttributeSet attrs) {
      super(context, attrs);

      mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

      mListViewFooter = LayoutInflater.from(context).inflate(
            R.layout.listview_footer, null, false);
   }

   @Override
   protected void onLayout(boolean changed, int left, int top, int right,
         int bottom) {
      super.onLayout(changed, left, top, right, bottom);
      // 初始化ListView对象
      if (mListView == null) {
         getListView();
      }
   }

   /**
    * 获取ListView对象
    */
   private void getListView() {
      int childs = getChildCount();
      if (childs > 0) {
         View childView = getChildAt(0);
         if (childView instanceof ListView) {
            mListView = (ListView) childView;
            // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载
            mListView.setOnScrollListener(this);
            Log.d(VIEW_LOG_TAG, "### 找到listview");
         }
      }
   }

   /*
    * (non-Javadoc)
    * 
    * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
    */
   private float mCurrentPosX;//初始状态  向上-缩放    坐标点信息
    private float mCurrentPosY;
    private float mDownX;//初始状态  向上-缩放    坐标点信息
    private float mDownY;
    private boolean isUpward = false;//是否向上
   @Override
   public boolean dispatchTouchEvent(MotionEvent event) {
      final int action = event.getAction();

      switch (action) {
      case MotionEvent.ACTION_DOWN:
         // 按下
         mYDown = (int) event.getRawY();
         
         mDownX = event.getX();
            mDownY = event.getY();
         break;

      case MotionEvent.ACTION_MOVE:
         // 移动
         mLastY = (int) event.getRawY();
         
         mCurrentPosX = event.getX();
          mCurrentPosY = event.getY();
         if (mCurrentPosY - mDownY < 0 && Math.abs(mCurrentPosX - mDownX) < 1){
             //向上-更多
             System.out.println("向上-----------");
             isUpward = true;
         }else if (mCurrentPosY - mDownY > 0 && Math.abs(mCurrentPosX - mDownX) < 10){
            //向下-刷新
            isUpward = false;
         }
         
         break;

      case MotionEvent.ACTION_UP:
         // 抬起
//       if (canLoad()) {
//          loadData();
//       }
         break;
      default:
         break;
      }

      return super.dispatchTouchEvent(event);
   }

   /**
    * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.
    * 
    * @return
    */
   private boolean canLoad() {
      return isListViewBottom() && !isLoading && isPullUp();
   }

   /**
    * 判断是否到了最底部(方法1)
    */
   private boolean isBottom() {
      if (mListView != null && mListView.getAdapter() != null && isUpward) {
         return mListView.getLastVisiblePosition() == (mListView
               .getAdapter().getCount() - 1);
      }
      return false;
   }
   //判断是否到了最底部(方法2)
   public boolean isListViewBottom() {
        boolean result = false;
        try {
           if (mListView != null && mListView.getAdapter() != null && isUpward) {
               if (mListView.getLastVisiblePosition() == (mListView.getCount() - 1)) {
                   final View bottomChildView = mListView.getChildAt(mListView.getLastVisiblePosition() - mListView.getFirstVisiblePosition());
                   result = (mListView.getHeight() >= bottomChildView.getBottom());
               }
            }
      } catch (Exception e) {
         result = false;
      }
        return result;
    }

   /**
    * 是否是上拉操作
    * 
    * @return
    */
   private boolean isPullUp() {
      return (mYDown - mLastY) >= mTouchSlop;
   }

   /**
    * 如果到了最底部,而且是上拉操作.那么执行onLoad方法
    */
   private void loadData() {
      if (mOnLoadListener != null) {
         // 设置状态
         setLoading(true);
         //
         mOnLoadListener.onLoad();
      }
   }

   /**
    * @param loading
    */
   public void setLoading(boolean loading) {
      isLoading = loading;
      if (isLoading) {
         mListView.addFooterView(mListViewFooter);
      } else {
         mListView.removeFooterView(mListViewFooter);
         mYDown = 0;
         mLastY = 0;
      }
   }

   /**
    * @param loadListener
    */
   public void setOnLoadListener(OnLoadListener loadListener) {
      mOnLoadListener = loadListener;
   }

   @Override
   public void onScrollStateChanged(AbsListView view, int scrollState) {
      switch (scrollState) {
      // 当不滚动时
        case SCROLL_STATE_IDLE:
            if (canLoad()) {
                  loadData();
            }
            break;
      }
   }

   @Override
   public void onScroll(AbsListView view, int firstVisibleItem,
         int visibleItemCount, int totalItemCount) {
      // 滚动时到了最底部也可以加载更多
//    if (canLoad()) {
//       loadData();
//    }
   }
   
   /**
    * 设置刷新
    */
   public static void setRefreshing(SwipeRefreshLayout refreshLayout,
         boolean refreshing, boolean notify) {
      Class<? extends SwipeRefreshLayout> refreshLayoutClass = refreshLayout
            .getClass();
      if (refreshLayoutClass != null) {

         try {
            Method setRefreshing = refreshLayoutClass.getDeclaredMethod(
                  "setRefreshing", boolean.class, boolean.class);
            setRefreshing.setAccessible(true);
            setRefreshing.invoke(refreshLayout, refreshing, notify);
         } catch (NoSuchMethodException e) {
            e.printStackTrace();
         } catch (IllegalAccessException e) {
            e.printStackTrace();
         } catch (InvocationTargetException e) {
            e.printStackTrace();
         }
      }
   }

   /**
    * 加载更多的监听器
    */
   public static interface OnLoadListener {
      public void onLoad();
   }
}
布局 文件为:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="11dp" >

        <ProgressBar
            android:id="@+id/pull_to_refresh_load_progress"
            style="@android:style/Widget.ProgressBar.Small.Inverse"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:indeterminate="true" />

        <TextView
            android:id="@+id/pull_to_refresh_loadmore_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_toRightOf="@+id/pull_to_refresh_load_progress"
            android:gravity="center"
            android:text="加载更多" />
    </RelativeLayout>

</RelativeLayout>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值