View的事件体系---V3.2 View的滑动

一、View的滑动一般通过以下三种方式实现:
a. 通过View本身提供的ScrollTo/ScrollBy方法

b. 通过动画给View施加平移效果来实现滑动

c. 通过改变View的LayoutParams参数使View重新布局来实现滑动效果

二、使用ScrollTo/ScrollBy

a. 这是View本身提供的实现滑动的方法

b. 通过对比源码发现,scrollBy也是调用了ScrollTo方法,实现了基于当前位置的相对滑动,scrollTo方法实现了基于所传递参数的绝对滑动

c. 在滑动过程中,mScrollX的值总是等于View左边缘和View内容左边缘在水平方向上的距离,mScrollY的值总是等于View上边缘和View内容上边缘在竖直方向上的距离。View的边缘指View的位置,有四个顶点组成,View内容的边缘是指View中的内容的边缘,scrollTo/scrollBy只能改变View内容的位置而不能改变View在布局中的位置

d. mScrollX mScrollY单位为像素,当View左边缘在View内容左边缘的右边时,mScrollX为正值,反之为负值。当View上边缘在View内容上边缘的下边时,mScrollY为正值,反之为负值。

e. 从左往右滑动,那么mScrollX为负值,反之为正值。当从上往下滑动时,mScrollY为负值,反之为正值。

三、使用动画

a. 使用动画是View进行滑动,主要对其translationX translationY两个属性进行修改,可以使用传统的View动画,也可以使用属性动画来完成

b. 采用View动画的话,可以通过anim文件,进行编写,如下

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="1000" android:fillAfter="true" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="100" android:toYDelta="100" android:interpolator="@android:interpolator/accelerate_decelerate" /></set>

c. 属性动画,更为简洁,如下

ObjectAnimator.ofInt(parent,"translationX",0,100).setDuration(1000).start();

d. 传统View动画和属性动画是有区别的,传统的View动画只是从表象上吧View进行了移动,但其本质并没有发生位置改变,如果注册过onclick事件,会发现移动后View点击是无效的,而有效点仍然在原位置,而属性动画的出现,很好的解决了这一问题。

四、通过改变布局参数

a. 通过改变LayoutParams参数,也可以实现View的滑动,示例如下

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) name.getLayoutParams(); params.leftMargin+=150; params.rightMargin+=150; name.setLayoutParams(params);

五、三种方式对比

a. ScrollTo/ScrollBy:操作简单,适用于对View内容的滑动

b. 动画:操作简单,适用于没有交互的View和实现复杂的动画效果

c. 改变布局参数:操作稍微复杂,适用于有交互的View

完整代码如下:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.example.zhonglq.myapplication;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private TextView name;

    private RelativeLayout parent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        name = (TextView) this.findViewById(R.id.name);
        parent = (RelativeLayout) this.findViewById(R.id.parent);


       FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        // 解决长按屏幕后无法拖动的现象
//        gestureDetector.setIsLongpressEnabled(false);
    }

    public void move(View view){
        Toast.makeText(this,"move",Toast.LENGTH_SHORT).show();
//        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) name.getLayoutParams();
//        params.leftMargin+=150;
//        params.rightMargin+=150;
//        name.setLayoutParams(params);
        parent.scrollTo(-30, 30);
        ObjectAnimator.ofInt(parent,"translationX",0,100).setDuration(1000).start();
    }

    GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
        /**
         * 手指轻轻触摸屏幕的一瞬间,1个Action_down触发
         * @param e
         * @return
         */
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }

        /**
         * 手指轻轻触摸屏幕,尚未松开或拖动,由1个Action_down触发
         * 与onDown相比,强调的是没有松开或者拖动的状态
         * @param e
         */
        @Override
        public void onShowPress(MotionEvent e) {

        }

        /**
         * 手指松开,伴随1个action_up
         * @param e
         * @return
         */
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        /**
         * 手指按下屏幕并拖动,1个ACTION_DOWN N个ACTION_MOVE
         * @param e1
         * @param e2
         * @param distanceX
         * @param distanceY
         * @return
         */
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }

        /**
         * 长按屏幕
         * @param e
         */
        @Override
        public void onLongPress(MotionEvent e) {

        }

        /**
         * 手指按下触摸屏,快速滑动后松开,强调的是快速滑动行为
         * @param e1
         * @param e2
         * @param velocityX
         * @param velocityY
         * @return
         */
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    });

    GestureDetector.OnDoubleTapListener onDoubleTapListener = new GestureDetector.OnDoubleTapListener() {

        /**
         * 严格的单击行为
         * 和onSingleTapUp的区别为,如果触发了onSingleTapConfirmed,那么后面不可能在紧跟着另外一个单击行为,
         * 这只可能是单击,而不是双击中的一次单击
         * @param e
         * @return
         */
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return false;
        }

        /**
         * 双击 两次连续的单击构成,不可能和onSingleTapConfirmed并存
         * @param e
         * @return
         */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return false;
        }

        /**
         * 表示发生了双击行为,在双击的期间,ACTION_DOWN ACTION_MOVE ACTION_UP都会触发此回调
         * @param e
         * @return
         */
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            return false;
        }
    };


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}</span>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值