【问题标题】:View Pager Double Tap查看寻呼机双击
【发布时间】:2013-10-03 09:02:40
【问题描述】:

我在我的应用程序中使用 ViewPager 来创建用于滑动图像的滑块。一切正常,除了我必须双击缩放图像。但是双击不适用于 ViewPager。我尝试了许多解决方案但无济于事。任何帮助表示赞赏。

谢谢

【问题讨论】:

    标签: android android-viewpager gesture touch-event


    【解决方案1】:

    我来不及回答这个问题,但如果有人仍在寻找解决方案:

    像这样创建一个类,只需复制粘贴代码并导入文件:

    点击here

    在您的 XML 中,您将 Pageradapter 的图像视图设置为执行以下操作:

     <your_package_name.TouchImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    
    
     </your_package_name.TouchImageView>
    

    在您的 PagerAdapter 中不要忘记使用:

     TouchImageView imageView = view.findViewById(R.id.imageView);
    

    所有功劳归https://github.com/MikeOrtiz/TouchImageView

    【讨论】:

      【解决方案2】:

      这个解决方案非常适合我。将这些行(interfaceonTouchEvent)添加到您的 CustomViewPager 中,如下所示:

      public class CustomViewPager extends ViewPager {
      
          //your variables
      
          private long previousClickTime = -1;
          private float x1 = -100, y1 = -100;
          private VPDoubleClickListener vpDoubleClickListener;
      
          //default build methods
      
          public interface VPDoubleClickListener{
              void onVPDoubleClicked();
          }
      
          public void setVPDoubleClickListener(VPDoubleClickListener vpDoubleClickListener){
              this.vpDoubleClickListener = vpDoubleClickListener;
          }
      
          @Override
          public boolean onTouchEvent(MotionEvent ev) {
              long nowClick = System.currentTimeMillis();
              float x2, y2;
              int action = ev.getAction();
              switch (action) {
                  case MotionEvent.ACTION_DOWN:{
                      x1 = ev.getX();
                      y1 = ev.getY();
                      break;
                  }
                  case MotionEvent.ACTION_UP:{
                      x2 = ev.getX();
                      y2 = ev.getY();
                      double space = Math.hypot(x2 - x1, y2 - y1);
                      //if distance of move < 25 -> ignore double tap
                      //300 milliseconds - double tap time threshold
                      if(space < 25 & nowClick - lastClick < 300){
                          if (vpDoubleClickListener != null) {
                              vpDoubleClickListener.onVPDoubleClicked();
                          }
                          Log.i("viewpager", "double tap");
                      }
                      lastClick = nowClick;
                      break;
                  }
                  default:break;
              }
              return super.onTouchEvent(ev);
          }
      
          //your custom methods
      
      }
      

      然后在父类中实现VPDoubleClickListener 并将setVPDoubleClickListener 设置为您的CustomViewPager,如下所示:

      public class CustomActivity implements CustomViewPager.VPDoubleClickListener {
      
          //...
          VPDoubleClickListener vpDoubleClickListener = this;
      
          @Override
          public void onVPDoubleClicked() {
              // Handle double tap event here!
              // Handle double tap event here!
              // Handle double tap event here!
              // Handle double tap event here!
              Log.d("TEST", "CustomViewPager double tap test.");
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_custom);
              initCustomViewPager();
              //...
      }
      
          private void initCustomViewPager(){
              CustomViewPager customViewPager = (CustomViewPager) findViewById(R.id.customViewPager);
              //...
              customViewPager.setVPDoubleClickListener(vpDoubleClickListener);
          }
      
          //your custom methods
      
      }
      

      然后在layout.xml(在本例中为activity_custom.xml)文件中使用&lt;com.your_username.your_app.your_package.CustomViewPager&gt;

      抱歉有错别字。

      【讨论】:

        【解决方案3】:

        我结合了 doubleTapIsLocked 变量、dispatchTouchEvent 和 GestureDetector。这可以检测双击和滑动。

        public class MainActivity extends AppCompatActivity {
        
            private static final String TAG = "MainActivity";
            private Boolean doubleTapIsLocked = false;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                setContentView(R.layout.activity_main);
        
                ViewPager myViewPager = (ViewPager) findViewById(R.id.pager);
                MyPagerAdapter myPagerAdapter = new MyPagerAdapter();
                myViewPager.setAdapter(myPagerAdapter);
        
            }
        
            @Override
            public boolean dispatchTouchEvent(MotionEvent ev) {
        
                if(!doubleTapIsLocked){gestureDetector.onTouchEvent(ev);}
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN://finger touching to the screen
                        break;
                    case MotionEvent.ACTION_MOVE://finger moving on the screen
        
                        break;
                    case MotionEvent.ACTION_UP://finger not touching to the screen
                        doubleTapIsLocked = false; //opens the lock
                        break;
                }
                return super.dispatchTouchEvent(ev);
            }
        
            //dedects the double tap and swipe
            //////////////////////////////Gesture started///////////////////////////////////////////////////
            GestureDetector.SimpleOnGestureListener simpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
        
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        
                    float sensitvity = 50;//50;
                    float distanceX = e1.getX() - e2.getX();//horizontal distance
                    float distanceY = e1.getY() - e2.getY();//vertical distance
        
                    if (Math.abs(distanceY) < Math.abs(distanceX)) {//finger moving horizontaly
        
                        Log.i(TAG, "horizontal move");
                        doubleTapIsLocked = true;//locks double tap
        
                    }
        
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
        
        
                @Override
                public boolean onDoubleTap(MotionEvent e) {//double tap
        
                    Log.i(TAG, "onDoubleTap");
        
                    return super.onDoubleTap(e);
                }
            };
            GestureDetector gestureDetector = new GestureDetector(simpleOnGestureListener);
            //////////////////////////////Gesture end/////////////////////////////////////////////////////
        

        【讨论】:

          【解决方案4】:

          使用该类进行图像捏合缩放和双击缩放

          import android.annotation.SuppressLint;
          import android.annotation.TargetApi;
          import android.content.Context;
          import android.graphics.Bitmap;
          import android.graphics.Matrix;
          import android.graphics.PointF;
          import android.util.AttributeSet;
          import android.util.Log;
          import android.view.MotionEvent;
          import android.view.ScaleGestureDetector;
          import android.view.View;
          import android.view.ViewGroup;
          import android.widget.FrameLayout;
          import android.widget.ImageView;
          
          public class TouchImageView extends ImageView {
          Matrix matrix = new Matrix();
          
          // We can be in one of these 3 states
          static final int NONE = 0;
          static final int DRAG = 1;
          static final int ZOOM = 2;
          int mode = NONE;
          //static  NonSwipeableViewPager PagerLeft;
          // Remember some things for zooming
          PointF last = new PointF();
          PointF start = new PointF();
          float minScale = 1f;
          float maxScale = 3f;
          float[] m;
          static boolean b =false, c= false;
          float redundantXSpace, redundantYSpace;
          
          float width, height;
          static final int CLICK = 3;
          float saveScale = 1f;
          float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
          
          ScaleGestureDetector mScaleDetector;
          
          Context context;
          ViewGroup vp;
          
          public TouchImageView(Context context) {
              super(context);
              sharedConstructing(context);
          }
          
          public TouchImageView(Context context, AttributeSet attrs) {
              super(context, attrs);
              sharedConstructing(context);
          }
          
          public void setChild(ViewGroup vp) {
              this.vp = vp;
          }
          
          private void sharedConstructing(Context context) {
              super.setClickable(true);
              this.context = context;
              mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
              matrix.setTranslate(1f, 1f);
              m = new float[9];
              setImageMatrix(matrix);
              setScaleType(ScaleType.MATRIX);
              setOnTouchListener(new OnTouchListener() {
                  @SuppressWarnings("deprecation")
                  @Override
                  public boolean onTouch(View v, MotionEvent event) {
                      mScaleDetector.onTouchEvent(event);
                      matrix.getValues(m);
                      float x = m[Matrix.MTRANS_X];
                      float y = m[Matrix.MTRANS_Y];
                      /*Log.v("log_tag",  event.getX()+" matrix "
                              + x);*/
                      PointF curr = new PointF(event.getX(), event.getY());
                      switch (event.getAction()) {
                      case MotionEvent.ACTION_DOWN:
                          TouchImageView.b = false;
                          Log.v("event","ACTION_DOWN");
                          last.set(event.getX(), event.getY());
                          start.set(last);
                          mode = DRAG;
                          break;
                      case MotionEvent.ACTION_MOVE:
                          if (mode == DRAG) {
                              float deltaX = curr.x - last.x;
                              float deltaY = curr.y - last.y;
                              float scaleWidth = Math.round(origWidth * saveScale);
                              float scaleHeight = Math.round(origHeight * saveScale);
                              if (scaleWidth < width) {
                                  deltaX = 0;
                                  if (y + deltaY > 0){
                                      TouchImageView.b = true;
                                      Log.v("event","ACTION_MOVE  scaleWidth < width   y + deltaY > 0");
                                      deltaY = -y;
                                  }
                                  else if (y + deltaY < -bottom){
                                      TouchImageView.b = false;
                                      Log.v("event","else ACTION_MOVE  scaleWidth < width   y + deltaY < -bottom");
                                      deltaY = -(y + bottom);
                                  }else{
                                      TouchImageView.b = false;
                                  }
                              } else if (scaleHeight < height) {
                                  deltaY = 0;
                                  if (x + deltaX > 0){
                                      TouchImageView.b = true;
                                      Log.v("event","ACTION_MOVE  scaleWidth < height x + deltaX > 0");
                                      deltaX = -x;
                                  }
                                  else if (x + deltaX < -right){
                                      TouchImageView.b = true;
                                      Log.v("event","ACTION_MOVE  scaleWidth < height x + deltaX < -right");
                                      deltaX = -(x + right);
                                  }else{
                                      TouchImageView.b = false;
                                  }
                              }else {
                                  if (x + deltaX > 0){
                                      TouchImageView.b = true;
                                      Log.v("event","scaleWidth > width");
                                      deltaX = -x;
                                  }
                                  else if (x + deltaX < -right){
                                      TouchImageView.b = true;
                                      Log.v("event","else scaleWidth > width");
                                      deltaX = -(x + right);
                                  }
                                  else{
                                      TouchImageView.b = true;
                                  }
                                  if (y + deltaY > 0){
                                      TouchImageView.b = true;
                                      Log.v("event","y + deltaY");
                                      deltaY = -y;
                                  }
                                  else if (y + deltaY < -bottom){
                                      TouchImageView.b = true;
                                      Log.v("event","y + deltaY < -bottom");
                                      deltaY = -(y + bottom);
                                  }else{
                                      TouchImageView.b = false;
                                  }
                              }
                              /*Log.v("log_tag",height + " matrix "
                                      + (int) getHeightFromMatrix(matrix, TouchImageView.this));*/
                              matrix.postTranslate(deltaX, deltaY);
                              last.set(curr.x, curr.y);
                          }
                          break;
          
                      case MotionEvent.ACTION_UP:
                          Log.v("event","ACTION_UP");
                          TouchImageView.b = true;
                          mode = NONE;
                          int xDiff = (int) Math.abs(curr.x - start.x);
                          int yDiff = (int) Math.abs(curr.y - start.y);
                          if (xDiff < CLICK && yDiff < CLICK){
                              Log.v("event","ACTION_UP  xDiff < CLICK && yDiff < CLICK");
                              performClick();
                          }
                          break;
          
                      case MotionEvent.ACTION_POINTER_UP:
                          //TouchImageView.b = false;
                          Log.v("event","ACTION_POINTER_UP");
                          mode = NONE;
                          break;
                      case MotionEvent.ACTION_POINTER_3_DOWN:
                          Log.v("event","ACTION_HOVER_MOVE");
                          break;
                      }
                      /*getLayoutParams().height = (int) getWidthFromMatrix(matrix,
                              TouchImageView.this);
                      getLayoutParams().width = (int) getHeightFromMatrix(matrix,
                              TouchImageView.this);*/
                      setImageMatrix(matrix);
                      invalidate();
                      return true;
                  }
              });
          }
          @Override
          public void setImageBitmap(Bitmap bm) {
              super.setImageBitmap(bm);
              if (bm != null) {
                  bmWidth = bm.getWidth();
                  bmHeight = bm.getHeight();
              }
          }
          
          public void setMaxZoom(float x) {
              maxScale = x;
          }
          
          private class ScaleListener extends
                  ScaleGestureDetector.SimpleOnScaleGestureListener {
              @Override
              public boolean onScaleBegin(ScaleGestureDetector detector) {
                  mode = ZOOM;
                  return true;
              }
          
              @SuppressLint("NewApi")
              @TargetApi(8)
              @Override
              public boolean onScale(ScaleGestureDetector detector) {
                  float mScaleFactor = (float) Math.min(
                          Math.max(.95f, detector.getScaleFactor()), 1.05);
                  float origScale = saveScale;
                  saveScale *= mScaleFactor;
                  if (saveScale > maxScale) {
                      saveScale = maxScale;
                      mScaleFactor = maxScale / origScale;
                  } else if (saveScale < minScale) {
                      saveScale = minScale;
                      mScaleFactor = minScale / origScale;
                  }
                  right = width * saveScale - width
                          - (2 * redundantXSpace * saveScale);
                  bottom = height * saveScale - height
                          - (2 * redundantYSpace * saveScale);
                  if (origWidth * saveScale <= width
                          || origHeight * saveScale <= height) {
                      matrix.postScale(mScaleFactor, mScaleFactor, width / 2,
                              height / 2);
                      if (mScaleFactor < 1) {
                          matrix.getValues(m);
                          float x = m[Matrix.MTRANS_X];
                          float y = m[Matrix.MTRANS_Y];
                          if (mScaleFactor < 1) {
                              if (Math.round(origWidth * saveScale) < width) {
                                  if (y < -bottom)
                                      matrix.postTranslate(0, -(y + bottom));
                                  else if (y > 0)
                                      matrix.postTranslate(0, -y);
                              } else {
                                  if (x < -right)
                                      matrix.postTranslate(-(x + right), 0);
                                  else if (x > 0)
                                      matrix.postTranslate(-x, 0);
                              }
                          }
                      }
                  } else {
                      matrix.postScale(mScaleFactor, mScaleFactor,
                              detector.getFocusX(), detector.getFocusY());
                      matrix.getValues(m);
                      float x = m[Matrix.MTRANS_X];
                      float y = m[Matrix.MTRANS_Y];
                      if (mScaleFactor < 1) {
                          if (x < -right)
                              matrix.postTranslate(-(x + right), 0);
                          else if (x > 0)
                              matrix.postTranslate(-x, 0);
                          if (y < -bottom)
                              matrix.postTranslate(0, -(y + bottom));
                          else if (y > 0)
                              matrix.postTranslate(0, -y);
                      }
                  }
                  return true;
              }
          }
          
          @Override
          protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
              width = MeasureSpec.getSize(widthMeasureSpec);
              height = MeasureSpec.getSize(heightMeasureSpec);
              // Fit to screen.
              float scale;
              float scaleX = (float) width / (float) bmWidth;
              float scaleY = (float) height / (float) bmHeight;
              scale = Math.min(scaleX, scaleY);
              matrix.setScale(scale, scale);
              setImageMatrix(matrix);
              saveScale = 1f;
          
              // Center the image
              redundantYSpace = (float) height - (scale * (float) bmHeight);
              redundantXSpace = (float) width - (scale * (float) bmWidth);
              redundantYSpace /= (float) 2;
              redundantXSpace /= (float) 2;
          
              matrix.postTranslate(redundantXSpace, redundantYSpace);
          
              origWidth = width - 2 * redundantXSpace;
              origHeight = height - 2 * redundantYSpace;
              right = width * saveScale - width - (2 * redundantXSpace * saveScale);
              bottom = height * saveScale - height
                      - (2 * redundantYSpace * saveScale);
              setImageMatrix(matrix);
          }
          
          /*public static void setPager(NonSwipeableViewPager pagerLeft) {
              PagerLeft = pagerLeft;
          }*/
          
          
          
            }
          

          在您的寻呼机适配器中执行此操作

          TouchImageView image_view=(TouchImageView)findViewById(R.id.your_image);
          

          【讨论】:

            【解决方案5】:

            这很棘手,但你也可以这样做:

            1. 为你的视图实现 onTouch 监听器
            2. 为当前时间戳取一个长变量=0
            3. 在 onTouch 方法中检查时间差 ((variable-system.currentTimeinMili)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多