美文网首页Android技术知识android技术专栏Android开发
Android控件拖动以及控件的onTouch事件与onClic

Android控件拖动以及控件的onTouch事件与onClic

作者: NapleC | 来源:发表于2017-04-06 22:39 被阅读546次

    一:

    原理就是响应控件的Touch事件,在Touch事件中对移动进行处理,如果没效果那你试着在布局文件中设置控件的 android:clickable="true"。
    当然,大部分人都是直接想要解决方案,这里直接贴代码,后面会有一些说明。

    • 1.首先在 你的 Activity 实现 OnTouchListener 接口 ,并重写onTouch 方法

      implements OnTouchListener

    • 2.activity中定义几个变量先

      private int screenWidth, screenHeight;
      private int lastX, lastY,moveDownX;
      private ImageView mTestIV;

    • 3.在Activity 的 onCreate方法中

        mTestIV=(ImageView) findViewById(R.id.iv_test); 
        mTestIV.setOnTouchListener(this);
        Display dis = this.getWindowManager().getDefaultDisplay();
        screenWidth = dis.getWidth();
        screenHeight = dis.getHeight();
      
    • 4.重写onTouch内部方法

      @Override
      public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            lastX = (int) event.getRawX();
            lastY = (int) event.getRawY();
            moveDownX= (int) event.getRawX();
        }
        if (event.getAction() == MotionEvent.ACTION_MOVE){
      
            int dx = (int) event.getRawX() - lastX;
            int dy = (int) event.getRawY() - lastY;
      
            int top = v.getTop() + dy;
      
            int left = v.getLeft() + dx;
      
            if (top <= 0) {
                top = 0;
            }
            if (top >= screenHeight - mTestIV.getHeight()) {
                top = screenHeight - mTestIV.getHeight();
            }
            if (left >= screenWidth - mTestIV.getWidth()) {
                left = screenWidth - mTestIV.getWidth();
            }
            if (left <= 0) {
                left = 0;
            }
            v.layout(left, top, left + mTestIV.getWidth(), top + mTestIV.getHeight());
            lastX = (int) event.getRawX();
            lastY = (int) event.getRawY();
        }
        if (event.getAction() == MotionEvent.ACTION_UP) {
            int tempDX = (int) event.getRawX() - moveDownX;
            if (Math.abs(tempDX) < 6) {
                // do your things
                return false;// 距离较小,当作click事件来处理
            }
        }
        return true;// 返回true,不执行click事件
      }
      

    以上为全部代码。

    二:

    现在我们来分析下实现步骤:

    一:我们开始要实现控件拖动效果

    原理比较简单:

    • 1.在按下的时候(MotionEvent.ACTION_DOWN),开始记录当前按下位置的坐标值;
    • 2.然后在手指移动控件的时候(MotionEvent.ACTION_MOVE),不断计算当前的位置的坐标并重绘控件的位置

    这里说明下 一些知识点:

    视图的left , top , right , bottom 的值是针对其父视图的相对位置,left相当于X轴值, top相当于Y轴值(原点为该widget 的父控件的左上角的点)
    getX是获取以widget左上角为坐标原点计算的X轴坐标值
    getRawX 获取的是以屏幕左上角为坐标原点计算的X轴坐标值

    做完以上步骤,可以实现正常的拖动,但这时候会发现,你拖动抬起手指后会执行onClick事件。
    现在分析下这件事出现的原因:
    在Android中,对一个View同时调用OnTouch事件和OnClick事件时,导致事件冲突。
    比如onClick事件打算执行A动作,OnTouch事件打算执行B动作,但是在实际使用时会发现,当调用OnTouch时,有可能会同时执行A,B两个动作,这是因为OnClick事件本身就是在OnTouch事件中发生的;
    在onTouch事件中,如果返回true,就不会执行onClick,返回false,就同时执行onClick方法,要想把OnTouch和onClick事件完全的区分。可能过下列方法,解决该冲突问题:  
    就是在 OnTouch中的MotionEvent.ACTION_DOWN 时,记录下点(X1,Y1),在 MotionEvent.ACTION_UP 时,记录下点(X2,Y2),然后比对 俩点之间的距离,如果小于一个较小数值(比如6),就认为是Click事件,onTouch中返回false,如果距离较大,可以当作onTouch事件去处理,返回true:

    相关文章

      网友评论

        本文标题:Android控件拖动以及控件的onTouch事件与onClic

        本文链接:https://www.haomeiwen.com/subject/zuxcattx.html