【问题标题】:Adding Fling Gesture to an image view - Android将 Fling 手势添加到图像视图 - Android
【发布时间】:2011-05-05 03:13:38
【问题描述】:

好的,我一直在这里引用代码:Fling gesture detection on grid layout

但就是不能让它工作。在我的主要活动中,我定义了一个简单的图像。我想检测图像上的一扔。下面是我的代码。底部的 onclick 方法是空的。是不是因为这个?我将其留空,因为在其他代码示例中它不是我想要的。我只想弹出一个简单的吐司,说向右或向左。

public class GestureRightLeft extends Activity implements OnClickListener  {

    ImageView peek;

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private GestureDetector gestureDetector;
    View.OnTouchListener gestureListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        peek =(ImageView) findViewById(R.id.peek);
        peek.setImageResource(R.drawable.bluestrip);

        gestureDetector = new GestureDetector(new MyGestureDetector());
        gestureListener = new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        };
    }

    class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;
                // right to left swipe
                if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Toast.makeText(GestureRightLeft.this, "Left Swipe", Toast.LENGTH_SHORT).show();
                }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Toast.makeText(GestureRightLeft.this, "Right Swipe", Toast.LENGTH_SHORT).show();
                }
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

    @Override
    public void onClick(View v) {}
}

【问题讨论】:

标签: android imageview gestures onfling


【解决方案1】:

这是我能想到的最简单的 flinger 工作版本。 实际上,您可以将它绑定到任何组件,而不仅仅是 ImageView。

public class MyActivity extends Activity {
    private void onCreate() {
        final GestureDetector gdt = new GestureDetector(new GestureListener());
        final ImageView imageView  = (ImageView) findViewById(R.id.image_view);
        imageView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(final View view, final MotionEvent event) {
                gdt.onTouchEvent(event);
                return true;
            }
        });
    }               

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    private class GestureListener extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Right to left
            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Left to right
            }

            if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Bottom to top
            }  else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Top to bottom
            }
            return false;
        }
    }
}

虽然 onClickListener 没有活动(如果您不需要捕获任何 onclick 操作) 它不仅可以捕获水平,还可以捕获垂直(如果不需要,只需删除垂直部分),并且水平滑动具有优先级,如您所见。 在方法返回的地方(我的 cmets 所在的地方)只需调用您的方法或其他任何方法 :)

【讨论】:

【解决方案2】:

试试这个

imageView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return false;
            }
            return true;
        }
  });

【讨论】:

  • +1 谢谢老兄它对我有用.. 我返回 true 而不是 false 。现在我的问题解决了
  • @contactmeandroid 里面如果条件我也返回 true;它对我有用。
  • @Ganapathy 它有效,但在滑动时我想拖动图像但我无法做到
  • android 中的拖放框架可能会对您有所帮助。developer.android.com/guide/topics/ui/drag-drop.html
  • 简化返回 !mGestureDetector.onTouchEvent(motionEvent);
【解决方案3】:
imageView.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return !gestureDetector.onTouchEvent(event);
    }
});

【讨论】:

    【解决方案4】:

    一些前置条件

    1) setonClick 方法

    image.setOnClickListener(this);
    

    2) 在 onTouch() 中设置手势检测

    image.setOnTouchListener(new OnTouchListener() {
        GestureDetector gestureDetector = new GestureDetector(new SwingGestureDetection((mContext),image,a));
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    });
    

    3) 创建 SwingGestureDetection 类并实现所有方法

    @Override
    public boolean onFling(MotionEvent start, MotionEvent finish, float arg2,float arg3) {
        if (start.getRawX() < finish.getRawX()) {
            System.out.println("next...swing");
        } else {
            System.out.println("previois...swing");
        }
    }
    

    4) 在构造函数中传递您的图像视图

    public SwingGestureDetection(Context con,ImageView image,int pos) {
        mContext = con;
        this.image = image;
        this.position = pos;
    }
    

    这对我来说是完美的工作。如果有任何疑问,请发表评论。

    【讨论】:

      【解决方案5】:

      尝试阅读: http://illusionsandroid.blogspot.com/2011/05/adding-fling-gesture-listener-to-view.html

      它允许您将活动实现与自定义侦听器分开。这只是对 Alex Orlov 报告的解决方案的重构

      【讨论】:

        【解决方案6】:

        如果您不喜欢创建单独的类或使代码复杂,
        你可以在 OnTouchListener 中创建一个 GestureDetector 变量,让你的代码更简单

        namVyuVar 可以是任何需要设置listner的View的名字

        namVyuVar.setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(View view, MotionEvent MsnEvtPsgVal)
            {
                flingActionVar.onTouchEvent(MsnEvtPsgVal);
                return true;
            }
        
            GestureDetector flingActionVar = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener()
            {
                private static final int flingActionMinDstVac = 120;
                private static final int flingActionMinSpdVac = 200;
        
                @Override
                public boolean onFling(MotionEvent fstMsnEvtPsgVal, MotionEvent lstMsnEvtPsgVal, float flingActionXcoSpdPsgVal, float flingActionYcoSpdPsgVal)
                {
                    if(fstMsnEvtPsgVal.getX() - lstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
                    {
                        // TskTdo :=> On Right to Left fling
        
                        return false;
                    }
                    else if (lstMsnEvtPsgVal.getX() - fstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
                    {
                        // TskTdo :=> On Left to Right fling
        
                        return false;
                    }
        
                    if(fstMsnEvtPsgVal.getY() - lstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
                    {
                        // TskTdo :=> On Bottom to Top fling
        
                        return false;
                    }
                    else if (lstMsnEvtPsgVal.getY() - fstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
                    {
                        // TskTdo :=> On Top to Bottom fling
        
                        return false;
                    }
                    return false;
                }
            });
        });
        

        【讨论】:

          【解决方案7】:

          如果您正在寻找像 ImageView.setOnGestureListener 这样的方法,则没有。你可以去看看Android源代码。您最好的选择是在 View 对象的 onTouch() 中处理它。

          这是我能做的最简单的 GestureDetector。

          我有一个名为 GenesMotionDetector.java 的类。这是它的代码:

          package gene.com.motioneventssample;
          
          import android.app.Activity;
          import android.os.Bundle;
          import android.view.GestureDetector;
          import android.view.MotionEvent;
          import android.widget.ImageView;
          import android.widget.LinearLayout;
          import android.widget.TextView;
          
          public class GenesMotionDetector extends Activity implements GestureDetector.OnGestureListener {
              private GestureDetector gestureScanner;
          
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.nothing);
                  gestureScanner= new GestureDetector(getBaseContext(),this);
              }
          
              @Override
              public boolean onTouchEvent(MotionEvent me) {
                  System.out.println("Inside onTouchEvent() of GenesMotionDetector.java");
                  return gestureScanner.onTouchEvent(me);
              }
          
              @Override
              public boolean onDown(MotionEvent e) {
                  System.out.println("Inside onDown() of GenesMotionDetector.java");
                  return true;
              }
          
              @Override
              public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                  System.out.println("Inside onFling() of GenesMotionDetector.java");
                  return true;
              }
          
              @Override
              public void onLongPress(MotionEvent e) {
                  System.out.println("Inside onLongPress() of GenesMotionDetector.java");
              }
          
              @Override
              public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                  System.out.println("Inside onScroll() of GenesMotionDetector.java");
                  return true;
              }
          
              @Override
              public void onShowPress(MotionEvent e) {
                  System.out.println("Inside onShowPress() of GenesMotionDetector.java");
              }
          
              @Override
              public boolean onSingleTapUp(MotionEvent e) {
                  System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java");
                  return true;
              }
          }
          

          该类对应的 XML 布局文件是 nothing.xml。这是它的代码:

          <?xml version="1.0" encoding="utf-8"?>
          
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/screen"
              android:orientation="vertical" android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <TextView
                  android:id="@+id/text"
                  android:background="#17528c"
                  android:text="testing"
                  android:layout_width="100dp"
                  android:layout_height="200dp" />
          
              <ImageView
                  android:id="@+id/image"
                  android:background="#f8af20"
                  android:layout_width="100dp"
                  android:layout_height="200dp" />
          </LinearLayout>
          

          现在,使用我可以(从上面)制作的最简单的 GestureDetector 并根据您的需要对其进行修改,我得到了:

          package gene.com.motioneventssample;
          
          import android.app.Activity;
          import android.os.Bundle;
          import android.view.GestureDetector;
          import android.view.MotionEvent;
          import android.view.VelocityTracker;
          import android.view.View;
          import android.widget.ImageView;
          
          public class GenesMotionDetector3 extends Activity implements GestureDetector.OnGestureListener {
              private GestureDetector gestureScanner;
              ImageView mView3;
          
              View.OnTouchListener gestureListener;
              MotionEvent initialME, finalME;
              private VelocityTracker mVelocityTracker = null;
          
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.nothing);
          
          
                  mView3 = (ImageView) findViewById(R.id.image);
          
                  // Gesture detection
                  gestureScanner = new GestureDetector(getBaseContext(), this);
          
                  gestureListener = new View.OnTouchListener() {
                      @Override
                      public boolean onTouch(View v, MotionEvent event) {
                          switch(event.getAction()){
                              case MotionEvent.ACTION_DOWN:
                                  initialME= event;
          
                                  if(mVelocityTracker == null) {
                                      // Retrieve a new VelocityTracker object to watch the velocity of a motion.
                                      mVelocityTracker = VelocityTracker.obtain();
                                  }
                                  else {
                                      // Reset the velocity tracker back to its initial state.
                                      mVelocityTracker.clear();
                                  }
                                  // Add a user's movement to the tracker.
                                  mVelocityTracker.addMovement(event);
          
                                  break;
                              case MotionEvent.ACTION_MOVE:
                                  mVelocityTracker.addMovement(event);
                                  // When you want to determine the velocity, call
                                  // computeCurrentVelocity(). Then call getXVelocity()
                                  // and getYVelocity() to retrieve the velocity for each pointer ID.
                                  mVelocityTracker.computeCurrentVelocity(1000);
                                  break;
                              case MotionEvent.ACTION_UP:
                                  finalME=event;
                                  break;
                              case MotionEvent.ACTION_CANCEL:
                                  // Return a VelocityTracker object back to be re-used by others.
                                  mVelocityTracker.recycle();
                                  break;
                          }
                          return onFling(initialME, finalME, mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
                          //return false;
                      }
                  };
          
                  mView3.setOnTouchListener(gestureListener);
              }
          
              @Override
              public boolean onTouchEvent(MotionEvent me) {
                  System.out.println("Inside onTouchEvent() of GenesMotionDetector.java");
          
                  return gestureScanner.onTouchEvent(me);
              }
          
              @Override
              public boolean onDown(MotionEvent e) {
                  System.out.println("Inside onDown() of GenesMotionDetector.java");
                  return true;
              }
          
              @Override
              public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                  System.out.println("Inside onFling() of GenesMotionDetector.java");
                  System.out.println("e1= "+ e1);
                  System.out.println("e2= "+ e2);
                  System.out.println("velocityX= "+ velocityX);
                  System.out.println("velocityY= "+ velocityY);
                  return true;
              }
          
              @Override
              public void onLongPress(MotionEvent e) {
                  System.out.println("Inside onLongPress() of GenesMotionDetector.java");
              }
          
              @Override
              public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                  System.out.println("Inside onScroll() of GenesMotionDetector.java");
                  return true;
              }
          
              @Override
              public void onShowPress(MotionEvent e) {
                  System.out.println("Inside onShowPress() of GenesMotionDetector.java");
              }
          
              @Override
              public boolean onSingleTapUp(MotionEvent e) {
                  System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java");
                  return true;
              }
          }
          

          你还不如在 onTouch() 中处理所有事情。我基本上是在 onTouch 中获取手势并将其传递给 onFling()。

          【讨论】:

            【解决方案8】:

            使用 ImageView 设计您的布局。 将setOnTouchListener添加到imageView.imageview.setOnTouchListener(this).添加未实现的方法View.OnTouchListener。然后onTouch方法您可以实现您的客座逻辑。这个示例告诉您从左到右和从右到左客座,

            float x1,x2;
            float y1, y2;
            
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch ( event.getAction() ){
            
                    case MotionEvent.ACTION_DOWN:{
                        x1 = event.getX();
                        y1 = event.getY();
                        break;
                    }
            
                    case MotionEvent.ACTION_UP:{
                        x2 = event.getX();
                        y2 = event.getY();
            
                        if ( x1<x2 ) {
                            //implement what you need to do here
                        }
                        if ( x1>x2 ) {
                            //implement what you need to do here
                        }
                        break;
                    }
                }
                return false;
            }
            

            【讨论】:

            • 答案不提供投掷逻辑,OP正在寻找。
            猜你喜欢
            • 1970-01-01
            • 2017-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多