Android监听ScrollView的滚动事件

一种可供用户滚动的层次结构布局容器,允许显示比实际多的内容。ScrollView是一种FrameLayout,意味需要在其上放置有自己滚动内容的子元素。子元素可以是一个复杂的对象的布局管理器。通常用的子元素是垂直方向的LinearLayout,显示在最上层的垂直方向可以让用户滚动的箭头。

有时候我们需要监听ScroView的滑动情况,比如滑动了多少距离,是否滑到布局的顶部或者底部。可惜的是SDK并没有相应的方法,不过倒是提供了一个 onScrollChanged方法,显然这个方法是不能被外界调用的,因此就需要把它暴露出去,方便使用。解决方式就是写一个接口。

 

protected void onScrollChanged(int x, int y, int oldx, int oldy) 

1、编写一个接口

 

 

public abstract interface OnScrollChangedListener {
	public abstract void onScrollChanged(int top, int oldTop);
}

2、然后重写ScrollView类的onScrollChanged方法,给它提供上面写的回调接口。

public class ObservableScrollView extends ScrollView {
	private OnScrollChangedListener onScrollChangedListener;

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

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

	public ObservableScrollView(Context context) {
		super(context);
	}
	
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		if(this.onScrollChangedListener != null) {
			onScrollChangedListener.onScrollChanged(t, oldt);
		}
	}

	public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {
		this.onScrollChangedListener = onScrollChangedListener;
	}

}

3、接下来,为了进一步体现滚动过程中监听事件触发的效果,可以在ScrollView滚动至一临界程度时通过AnimationListener处理两个Animation动画效果:<alpha android:interpolator透明度渐变和<scale android:interpolator大小伸缩。

 

编写一个动画监听器MyAnimationListener,在Animation动画效果开始执行前,执行完毕和重复执行时可以触发监听器,从而执行对应的函数。

 

public class MyAnimationListener implements AnimationListener {
	private View mAnimView;
	private boolean mAnimIn;
	
	public MyAnimationListener(View animView, boolean animIn) {
		mAnimView = animView;
		mAnimIn = animIn;
	}

	@Override
	public void onAnimationEnd(Animation animation) {
		if(!mAnimIn) {
			mAnimView.setVisibility(View.INVISIBLE);
		}
	}

	@Override
	public void onAnimationRepeat(Animation animation) {}

	@Override
	public void onAnimationStart(Animation animation) {
		if(mAnimIn) {
			mAnimView.setVisibility(View.VISIBLE);
		}
	}

}

4、WelcomeActivity.java

public class WelcomeActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		setContentView(R.layout.activity_welcome);		
		Intent intent=new Intent();
		intent.setClass(this,  GuiteActivity.class);
		startActivity(intent);	
			finish();
		
	}	
}

5、GuiteActivity.java

 

 

public class GuiteActivity extends FragmentActivity implements OnGlobalLayoutListener ,OnScrollChangedListener   {

	private ObservableScrollView mScrollView;
	private View mAnimView;
	private int mScrollViewHeight;
	private int mStartAnimateTop;
	private Button btnSkip;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	setContentView(R.layout.guide);
		
		mScrollView = (ObservableScrollView)this.findViewById(R.id.scrollView1);
		mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(this);
		mScrollView.setOnScrollChangedListener(this);
		
		btnSkip=(Button)mScrollView.findViewById(R.id.btnSkip);
		btnSkip.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				finish();
			}
		});
		
		
		
		mAnimView = this.findViewById(R.id.anim1);
		mAnimView.setVisibility(View.INVISIBLE);
	}

	

	@Override
	public void onGlobalLayout() {
		mScrollViewHeight = mScrollView.getHeight();
		mStartAnimateTop = mScrollViewHeight / 3 * 2;
	}

	boolean hasStart = false;
	@Override
	public void onScrollChanged(int top, int oldTop) {
		int animTop = mAnimView.getTop() - top;
		
		if(top > oldTop) {
			if(animTop < mStartAnimateTop && !hasStart) {
				Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.feature_anim2scale_in);
				anim1.setAnimationListener(new MyAnimationListener(mAnimView, true));
				
				mAnimView.startAnimation(anim1);
				hasStart = true;
			}
		} else {
			if(animTop > mStartAnimateTop && hasStart) {
				Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.feature_alpha_out);
				anim1.setAnimationListener(new MyAnimationListener(mAnimView, false));
				
				mAnimView.startAnimation(anim1);
				hasStart = false;
			}
		}
	}
}

6、feature_alpha_out.xml

 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<alpha android:interpolator="@android:anim/overshoot_interpolator"
		android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" />
</set>

7、feature_anim2scale_in.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<scale android:interpolator="@android:anim/overshoot_interpolator"
	android:duration="200" android:pivotX="50.0%" android:pivotY="50.0%"
	android:fillAfter="true" android:fromXScale="0.0" android:toXScale="1.0"
	android:fromYScale="0.0" android:toYScale="1.0"
	xmlns:android="http://schemas.android.com/apk/res/android" />

 

简单的项目结构如下

运行效果






 

posted @ 2016-10-14 00:08  海的心  阅读(698)  评论(0编辑  收藏  举报