滑动,与用户直观交互

任何app无论功能的多少,最终都会落实到与用户交互上,在这里咱们就一起去看看与用户交互最深切感受的滑动。
滑动无非就是view自己在parent中的移动,再者就是parent移动(view形式上的滑动,其实只是隐形的欺骗了一下用户的眼睛)。这里谈到友好交互,就不再大批量的文字让你看的作呕。
一:view自己滑动
1.设置margin

public class LayoutParamsSSS extends LinearLayout {
    public LayoutParamsSSS(Context context) {
        this(context, null, 0);
    }

    public LayoutParamsSSS(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LayoutParamsSSS(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed,l,t,r,b);
    }

    private int lastX;
    private int lastY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //记录触摸点坐标
                lastX = rawX;
                lastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE:
                //计算偏移量
                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;
                //设置它的LayoutParams(这里用了一个巧方式,因为任何ViewGroup都有MarginLayoutParams)
                ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
//                setLayoutParams(layoutParams);//和requestLayout()方法一样
                requestLayout();
                //重新设置初始坐标
                lastX = rawX;
                lastY = rawY;
                break;
        }
        return super.onTouchEvent(event);
    }
}

2.设置layout

//在当前left、top、right、bottom的基础上加上偏移量
 layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom() + offsetY);

3.设置View所在矩阵Rect

//设置X和Y上的偏移量
                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);

4.使用属性动画

public class AnimatorSSS extends View {
    private Scroller mScroller;

    public AnimatorSSS(Context context) {
        this(context, null, 0);
    }

    public AnimatorSSS(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AnimatorSSS(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context, new BounceInterpolator());
    }

    private float lastX = 0;
    private float lastY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float firstX = event.getRawX();
        float firstY = event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                ViewHelper.setTranslationX(this, ViewHelper.getTranslationX(this) + firstX - lastX);
                ViewHelper.setTranslationY(this, ViewHelper.getTranslationY(this) + firstY - lastY);
                break;
            case MotionEvent.ACTION_UP:
                smoothScrollTo(100, 100);
                break;
            default:
                break;
        }
        lastX = firstX;
        lastY = firstY;
        return super.onTouchEvent(event);
    }

    private int lastTranslationX = 0;
    private int lastTranslationY = 0;

    private void smoothScrollTo(int desX, int desY) {
        mScroller.startScroll(lastTranslationX - desX, lastTranslationY - desY, (int) ViewHelper
                .getTranslationX(this) - lastTranslationX, (int) ViewHelper.getTranslationY(this) -
                lastTranslationY);
        lastTranslationX = (int) ViewHelper.getTranslationX(this);
        lastTranslationY = (int) ViewHelper.getTranslationY(this);
        invalidate();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }
}

二:parent移动
1.scrollTo和scrollBy

public class ScrollBySSS extends LinearLayout {
    public ScrollBySSS(Context context) {
        this(context, null, 0);
    }

    public ScrollBySSS(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollBySSS(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed,l,t,r,b);
        ((View)getParent()).getLocationOnScreen(mm);
    }
    private int[] mm = new int[2];
//    private int lastX;
//    private int lastY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //记录触摸点坐标
//                lastX = rawX;
//                lastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE:
                //计算偏移量
//                int offsetX = rawX - lastX;
//                int offsetY = rawY - lastY;
                //设置它的LayoutParams(这里用了一个巧方式,因为任何ViewGroup都有MarginLayoutParams)
//                ((View)getParent()).scrollBy(-offsetX,-offsetY);
                ((View)getParent()).scrollTo(-rawX + mm[0], -rawY + mm[1]);
                //重新设置初始坐标
//                lastX = rawX;
//                lastY = rawY;
                break;
        }
        return super.onTouchEvent(event);
    }
}

2.scroller类

public class ScrollerSSS extends LinearLayout {
    private Scroller mScroller;
    public ScrollerSSS(Context context) {
        this(context, null, 0);
    }

    public ScrollerSSS(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollerSSS(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context,new BounceInterpolator());
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }
    private int lastX;
    private int lastY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //记录触摸点坐标
                lastX = rawX;
                lastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE:
                //计算偏移量
                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;
                ((View)getParent()).scrollBy(-offsetX,-offsetY);
                //重新设置初始坐标
                lastX = rawX;
                lastY = rawY;
                break;
            case MotionEvent.ACTION_UP:
                //手指离开,回弹
                View parent = (View) getParent();
                mScroller.startScroll(parent.getScrollX(),parent.getScrollY(),-parent.getScrollX(),-parent.getScrollY(),1000);
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        //判断Scroller是否执行完毕
        if (mScroller.computeScrollOffset()){
            ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            //通过重绘来不断调用computeScroll
            invalidate();
        }
    }
}

ok了,暂时就这么多,坐标还真难调!!!!!!!!!!

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值