触摸点的位置及滑动属性
getRowX:触摸点距离屏幕左边的距离,即绝对坐标
getX: 触摸点相对于控件左边的距离,即视图坐标
getTop: View自身顶边相对于父view顶边的距离
getLeft: View自身左边相对于父view左边的距离
getHeight:返回当前View的高度
getMeasuredHeight:返回当前View的高度(似乎一样)
getScrollX(Y):(源码中分别return mScrollX和mScrollY)
(mScrollX和mScrollY是视图在X轴和Y轴的偏移量)
其值为屏幕上边缘对应的View视图上面的刻度值,初始化时上边缘对应的View视图刻度为0,即视图初始化时getScrollY值为0(getScrollX同理)
因此,当向上滑动时,getScrollY的值处于增加状态
而对于getScrollX,向左侧滑动时其值增加
对于scrollTo()和scrollBy():
【移动开发】View的scrollTo()和scrollBy()区别
http://blog.youkuaiyun.com/manoel/article/details/39228593
从源码中可以看到,scrollBy()的内部其实是调用了scrollTo()。在scrollTo()中,调用了onScrollChanged()和invalidate()。
总结一下,scrollTo()是一步到位,而scrollBy()是逐步累加。
scrollTo()用来响应点击事件会比较好,而scrollBy()常用在滑动状态,即MotionEvent.ACTION_MOVE:状态,move事件
WindowManager wm = (WindowManager) context.getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
int mScreenHeight = dm.heightPixels;//此为当前屏幕的高度(减去50为当前Activity界面的高度)
public class MyScrollView extends ViewGroup {
private int mScreenHeight;
private Scroller scroller;
private int lastY;
private int start;
public MyScrollView(Context context) {
super(context);
initView(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
mScreenHeight = dm.heightPixels;//此为当前屏幕的高度(减去50为当前界面的高度)
scroller = new Scroller(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
//设置ViewGroup的高度
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
mlp.height = mScreenHeight*childCount;
setLayoutParams(mlp);
//放置子View
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
if (childView.getVisibility()!=View.GONE){
childView.layout(l,i*mScreenHeight,
r,(i+1)*mScreenHeight);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int count = getChildCount();//获得子控件的数量
//遍历通知子View进行测量
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);//返回指定索引处的视图
measureChild(childView,widthMeasureSpec,heightMeasureSpec);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int y = (int) event.getY();//getY相对于控件本身的位置(getRowX(Y):触摸点相对于屏幕的坐标)
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//记录触摸起点
lastY = y;
start = getScrollY();
break;
case MotionEvent.ACTION_MOVE:
if (!scroller.isFinished()){
scroller.abortAnimation();
}
int dy = lastY - y;
if (getScrollY()<0){
dy = 0;
}
Log.i("TAGTEST","event.getY(): "+event.getY());
Log.i("TAGTEST","event.getRawY(): "+event.getRawY());
Log.i("TAGTEST","getScrollY: "+getScrollY());
Log.i("TAGTEST","getHeight: "+getHeight());
Log.i("TAGTEST","getMeasuredHeight: "+getMeasuredHeight());
Log.i("TAGTEST","mScreenHeight: "+mScreenHeight);
Log.i("TAGTEST","getHeight()mScreenHeight: "+(getHeight()-mScreenHeight));
if (getScrollY()>getHeight()-mScreenHeight){
dy=0;
}
scrollBy(0,dy);
lastY = y;
break;
case MotionEvent.ACTION_UP:
//记录触摸终点
int dScroll = checkAlignment();//滑动距离(下滑为正数)
if (dScroll>0){//上滑
if (dScroll<mScreenHeight/3){//滑动距离小于屏幕的三分之一
scroller.startScroll(0,getScrollY(),0,-dScroll);
}else {
scroller.startScroll(0,getScrollY(),0,
mScreenHeight-dScroll);
}
}else {//下滑
if (-dScroll<mScreenHeight/3){//滑动距离小于屏幕的三分之一
scroller.startScroll(0,getScrollY(),0,-dScroll);
}else {
scroller.startScroll(0,getScrollY(),0,
-mScreenHeight-dScroll);
}
}
break;
}
postInvalidate();//刷新界面
return true;
}
private int checkAlignment(){
int end = getScrollY();
boolean isUp = (end - start)>0?true:false;
int lastPrev = end%mScreenHeight;
int lastNext = mScreenHeight - lastPrev;
if (isUp){
//向上的
return lastPrev;
}else {
return -lastNext;
}
}
@Override//配合使用Scroller实例,我们就可以获得当前应该的偏移坐标,
// 手动使View/ViewGroup偏移至该处。
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()){//滑动尚未完成
scrollTo(0,scroller.getCurrY());//
postInvalidate();//刷新界面
}
}
}