先上源码:
package com.yxl.scrowview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;
public class FTScrollView1 extends ScrollView {
public FTScrollView1(Context context) {
this(context, null);
}
public FTScrollView1(Context context, AttributeSet attrs) {
this(context, null, 0);
}
public FTScrollView1(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, null, 0);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
}
private float firstY = 0;
private View tv ;
//当加载完XML文件里就会调用这个方法
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
tv = getChildAt(0);
}
}
boolean isup = false;
int endY = 0;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
firstY = ev.getY();
endY = tv.getBottom();
break;
case MotionEvent.ACTION_MOVE:
float tempY = ev.getY();
int temp = (int) (firstY - tempY);
//System.out.println(temp);
scrollBy((int)ev.getX(), temp);
firstY = tempY;
if(isNeedMove()) {
// System.out.println(temp);
// System.out.println((tv.getTop()) + ":" + (tv.getBottom()));
tv.layout(tv.getLeft(), tv.getTop() - temp,
tv.getRight(), tv.getBottom() - temp);
isup = true;
//System.out.println(tv.getY());
}
return true;
case MotionEvent.ACTION_UP:
if(isup) {
TranslateAnimation translate = new TranslateAnimation(tv.getX(), tv.getX(), tv.getTop(), 0);
System.out.println(tv.getTop());
translate.setDuration(200);
tv.setAnimation(translate);
tv.layout(tv.getLeft(), 0,
tv.getRight(), endY);
isup = false;
}
System.out.println(tv.getTop());
break;
default:
break;
}
return super.onTouchEvent(ev);
}
public boolean isNeedMove() {
int offset = tv.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
}
}
源码解释:
1.首先通过protected void onFinishInflate()这个方法获得里面的子View;ScrollView的子View只能是一个;
2、响应触摸事件:
在OntouchEvent后时 Down后获得最开始的Y坐标;通过Move事件得到 新Y坐标;Scrollby来移动View的位置(这个方法是移动本类里的内容);如果移动的位置等于0或者等于最大值则就不会在变化,那么这个时候就是移动到最上面或者最下面的位置了;要想子View在滑动出一个框 来就得用View.layout()这个方法;在移动的过程中,把这个layout变得更大;当Up事件后,为子View添加一个移动动画;也可以用Scroller;这里用的是TranslateAna;最后在用Layout把子View放回到最初位置(此处有个注意事项:View.layout这个方法即把这个子View给放到哪个位置去,那么放到哪个位置后,哪个位置就是开始坐标了(0,0),但这只是对于Translate而说;而View.layout这个方法的坐标是针对于父窗口的)这里最好是Debug看看坐标