要实现一个功能:当Scrollview滑动到最底端的时候需要触发事件加载其他数据。很多人都以为ScrollView可以像ListViev那样setOnScrollListener,其实沒那么简单,因为ScrollView压根就没有该接口,在baidu上兜了一圈没有找到合适的答案,没办法只能google去了,居然一下子解决了这个问题,还是老外比较牛,呵呵,这是我访问的网址:
http://stackoverflow.com/questions/2864563/how-do-i-know-that-the-scrollview-is-already-scrolled-to-the-bottom
注意,如果数据不满一页的话,会执行onBottom方法!通常要使用懒加载的话数据都会超过一页,所以我沒仔细考虑这个问题!
用的时候也很简单,通常这样使用:
顺便记一下老外使用fullScroll的做法。当然也可以直接fullScroll而不需要放入post()。
http://stackoverflow.com/questions/2864563/how-do-i-know-that-the-scrollview-is-already-scrolled-to-the-bottom
注意,如果数据不满一页的话,会执行onBottom方法!通常要使用懒加载的话数据都会超过一页,所以我沒仔细考虑这个问题!
我把ScrollView封装成类了,源码如下:
package com.ql.view; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.ScrollView; public class LazyScrollView extends ScrollView{ private static final String tag="LazyScrollView"; private Handler handler; private View view; public LazyScrollView(Context context) { super(context); // TODO Auto-generated constructor stub } public LazyScrollView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public LazyScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } //这个获得总的高度 public int computeVerticalScrollRange(){ return super.computeHorizontalScrollRange(); } public int computeVerticalScrollOffset(){ return super.computeVerticalScrollOffset(); } private void init(){ this.setOnTouchListener(onTouchListener); handler=new Handler(){ @Override public void handleMessage(Message msg) { // process incoming messages here super.handleMessage(msg); switch(msg.what){ case 1: if(view.getMeasuredHeight() <= getScrollY() + getHeight()) { if(onScrollListener!=null){ onScrollListener.onBottom(); } }else if(getScrollY()==0){ if(onScrollListener!=null){ onScrollListener.onTop(); } } else{ if(onScrollListener!=null){ onScrollListener.onScroll(); } } break; default: break; } } }; } OnTouchListener onTouchListener=new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: if(view!=null&&onScrollListener!=null){ handler.sendMessageDelayed(handler.obtainMessage(1), 200); } break; default: break; } return false; } }; /** * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。 */ public void getView(){ this.view=getChildAt(0); if(view!=null){ init(); } } /** * 定义接口 * @author admin * */ public interface OnScrollListener{ void onBottom(); void onTop(); void onScroll(); } private OnScrollListener onScrollListener; public void setOnScrollListener(OnScrollListener onScrollListener){ this.onScrollListener=onScrollListener; } }
用的时候也很简单,通常这样使用:
scrollView=(LazyScrollView)findViewById(R.id.scrollView); scrollView.getView(); scrollView.setOnScrollListener(new OnScrollListener() { @Override public void onTop() { // TODO Auto-generated method stub Log.d(tag,"------滚动到最上方------"); } @Override public void onScroll() { // TODO Auto-generated method stub Log.d(tag,"没有到最下方,也不是最上方"); } @Override public void onBottom() { // TODO Auto-generated method stub Log.d(tag,"------滚动到最下方------"); } });
顺便记一下老外使用fullScroll的做法。当然也可以直接fullScroll而不需要放入post()。
scrollView.post(new Runnable() { @Override public void run() { scrollView.fullScroll(View.FOCUS_DOWN); } });