View的属性值

触摸点的位置及滑动属性

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();//刷新界面
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值