Android的ScrollView没有像ListView那样,使用setOnScrollListener监听滑动事件,通过自定义的View可以实现,源码如下:
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,"------滚动到最下方------");
}
});
补充一点:
控制ScrollView滑动到底部,可以使用scrollTo方法,但是相比之下,fullScroll方法:
scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部;
scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部。
需要注意的是,该方法不能直接被调用,
因为Android很多函数都是基于消息队列来同步,
所以需要一部操作,addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快,
但是如果立即调用fullScroll, view可能还没有显示出来,所以会失败应该通过handler在新线程中更新:
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});