android开发中ListView的妙用之:下拉刷新与到底部载入更多源码

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天项目也快结束了,就写篇博客吧,记录一下我对ListView的下拉刷新与底部载入更多的一点理解[/b]</span>
首先我们知道ListView是没有下拉刷新的接口的,我们要借助现有的功能去扩展更多的功能我们就需要对ListView做一点修改,使它满足我们的需求:
一、ListView的表面理解就是List的格式显示的View,也就是要一行一行的显示,对ListView添加适配器这是必不可少的。所以我们修改以后的ListView当然也可以添加适配器等等常见的对ListView的操作;
二、要捕捉我们对列表界面的操作,下拉或者滚动到底部必须要有对事件的监听器,这里就尤为重要了,我们知道对按钮添加监听器,我们可以捕获到我们对某个按钮施加了操作,然后就执行我们的操作,这里的下拉或者滚动到底部,我们当然也需要捕捉到这个动作,然后执行我们想要执行的动作;
三、原理我们知道啦,现在就剩下怎么去捕获这个动作,然后捕获动作后我们怎么添加入我们想要的操作。只要捕获到动作,你想干什么我不关心,因为需求各式各样;
四、在捕获到动作以后我们开始给用户点反应。。。。。
[b]下边我们来看看这个Demo的代码
一、继承ListView
package com.example.pulldownview;


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;




/**
 * <p>一个可以监听ListView是否滚动到最顶部或最底部的自定义控件</p>
 * 只能监听由触摸产生的,如果是ListView本身Flying导致的,则不能监听</br>
 * 如果加以改进,可以实现监听scroll滚动的具体位置等
 * @author solo ho</br> Email:kjsoloho@gmail.com
 */


public class ScrollOverListView extends ListView {


	private static final String TAG = "ScrollOverListView";
	private static final boolean DEBUG = false;
	private int mLastY;
	private int mTopPosition;
	private int mBottomPosition;


	public ScrollOverListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}


	public ScrollOverListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}


	public ScrollOverListView(Context context) {
		super(context);
		init();
	}


	private void init(){
		mTopPosition = 0;
		mBottomPosition = 0;
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			if (DEBUG) Log.d(TAG, "onInterceptTouchEvent Action down");
			mLastY = (int) ev.getRawY();
		}
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		final int action = ev.getAction();
		final int y = (int) ev.getRawY();
		
		boolean isHandled = false;
		switch(action){
			case MotionEvent.ACTION_DOWN:{
				if (DEBUG) Log.d(TAG, "action down");
				mLastY = y;
				isHandled = mOnScrollOverListener.onMotionDown(ev);
				if (isHandled) {
					break;
				}
				break;
			}
			
			case MotionEvent.ACTION_MOVE:{
				if (DEBUG) Log.d(TAG, "action move");
				final int childCount = getChildCount();
				if(childCount == 0) {
					break;
				}
				
				final int itemCount = getAdapter().getCount() - mBottomPosition;
				
				final int deltaY = y - mLastY;
				if (DEBUG) Log.d(TAG, "lastY=" + mLastY +" y=" + y);
				
				final int firstTop = getChildAt(0).getTop();
				final int listPadding = getListPaddingTop();
				
				final int lastBottom = getChildAt(childCount - 1).getBottom();
				final int end = getHeight() - getPaddingBottom();
				
				final int firstVisiblePosition = getFirstVisiblePosition();
				
				isHandled = mOnScrollOverListener.onMotionMove(ev, deltaY);
				
				if(isHandled){
					break;
				}
				
				//DLog.d("firstVisiblePosition=%d firstTop=%d listPaddingTop=%d deltaY=%d", firstVisiblePosition, firstTop, listPadding, deltaY);
				if (firstVisiblePosition <= mTopPosition && firstTop >= listPadding && deltaY > 0) {
					if (DEBUG) Log.d(TAG, "action move pull down");
		            isHandled = mOnScrollOverListener.onListViewTopAndPullDown(ev, deltaY);
		            if(isHandled){
		            	break;
		            }
		        }
				
				// DLog.d("lastBottom=%d end=%d deltaY=%d", lastBottom, end, deltaY);
		        if (firstVisiblePosition + childCount >= itemCount && lastBottom <= end && deltaY < 0) {
		        	if (DEBUG) Log.d(TAG, "action move pull up");
		        	isHandled = mOnScrollOverListener.onListViewBottomAndPullUp(ev, deltaY);
		        	if(isHandled){
		        		break;
		        	}
		        }
				break;
			}
			
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:{
				if (DEBUG) Log.d(TAG, "action move pull up");
				isHandled = mOnScrollOverListener.onMotionUp(ev);
				if (isHandled) {
					break;
				}
				break;
			}
		}
		
		mLastY = y;
		if (isHandled) {
			return true;
		}
		return super.onTouchEvent(ev);
	}
	
	
	/**空的*/
	private OnScrollOverListener mOnScrollOverListener = new OnScrollOverListener(){


		@Override
		public boolean onListViewTopAndPullDown(MotionEvent event, int delta) {
			return false;
		}


		@Override
		public boolean onListViewBottomAndPullUp(MotionEvent event, int delta) {
			return false;
		}


		@Override
		public boolean onMotionDown(MotionEvent ev) {
			return false;
		}


		@Override
		public boolean onMotionMove(MotionEvent ev, int delta) {
			return false;
		}


		@Override
		public boolean onMotionUp(MotionEvent ev) {
			return false;
		}
		
	};
	
	
	
	
	
	
	
	// =============================== public method ===============================


	/**
	 * 可以自定义其中一个条目为头部,头部触发的事件将以这个为准,默认为第一个
	 * 
	 * @param index 正数第几个,必须在条目数范围之内
	 */
	public void setTopPosition(int index){
		if(index < 0)
			throw new IllegalArgumentException("Top position must > 0");
		
		mTopPosition = index;
	}
	
	/**
	 * 可以自定义其中一个条目为尾部,尾部触发的事件将以这个为准,默认为最后一个
	 * 
	 * @param index 倒数第几个,必须在条目数范围之内
	 */
	public void setBottomPosition(int index){
		if(index < 0)
			throw new IllegalArgumentException("Bottom position must > 0");
		
		mBottomPosition = index;
	}


	/**
	 * 设置这个Listener可以监听是否到达顶端,或者是否到达低端等事件</br>
	 * 
	 * @see OnScrollOverListener
	 */
	public void setOnScrollOverListener(OnScrollOverListener onScrollOverListener){
		mOnScrollOverListener = onScrollOverListener;
	}
	
	/**
	 * 滚动监听接口</br>
	 * @see ScrollOverListView#setOnScrollOverListener(OnScrollOverListener)
	 * 
	 * @author solo ho</br> Email:kjsoloho@gmail.com
	 */
	public interface OnScrollOverListener {
		
		/**
		 * 到达最顶部触发
		 * 
		 * @param delta 手指点击移动产生的偏移量
		 * @return 
		 */
		boolean onListViewTopAndPullDown(MotionEvent event, in
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值