2016-09-03 17 views
8

Tôi đang thực hiện swipe card với pinch to zoom chức năng sử dụng this thư viện và khi tôi sử dụng chỉ image view phương tiện tốt sau đó nó làm việc swipe hoạt động đúng nhưng tôi muốn chức năng swipe như thư viện cũng như pinch to zoom nên Tôi đã thêm TouchImageView lớp trong đó chỉ pinch to zoom hoạt động nhưng chức năng vuốt không hoạt động. Vì vậy, bạn có thể vui lòng giúp tôi giải quyết vấn đề này hoặc đề xuất cho tôi bất kỳ thư viện thay thế nào trong đó swipe cardpinch to zoom là có thể. Dưới đây là hoạt động của tôithẻ swipe Android với pinch để phóng to ImageView sử dụng SwipeFlingAdapterView thư viện

public class MainActivity extends AppCompatActivity{ 

    private SwipeFlingAdapterView flingContainer; 
    public static ArrayList<SwipModel> al; 
    public SwipViewAdapter swipViewAdapter; 
    private SwipModel swipModel; 
    private Uri uri; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     getId(); 
     setSwipeCard(); 

    } 

    private void getId() { 
     flingContainer = (SwipeFlingAdapterView) findViewById(R.id.frame); 
    } 

    private void setSwipeCard() { 

     uri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/drawable/picture1"); 

     swipModel = new SwipModel(); 

     al = new ArrayList<>(); 
     swipModel.setCardImageDrawable(uri); 
     al.add(swipModel); 


     swipViewAdapter = new SwipViewAdapter(getApplicationContext(), al); 

     flingContainer.setAdapter(swipViewAdapter); 
     flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() { 
      @Override 
      public void removeFirstObjectInAdapter() { 
       // this is the simplest way to delete an object from the Adapter (/AdapterView) 
       Log.d("LIST", "removed object!"); 
//    al.remove(0); 
//    swipViewAdapter.notifyDataSetChanged(); 
      } 

      @Override 
      public void onLeftCardExit(Object dataObject) { 
       //Do something on the left! 
       //You also have access to the original object. 
       //If you want to use it just cast it (String) dataObject 
//    makeToast(MainActivity.this, "Left!"); 
      } 

      @Override 
      public void onRightCardExit(Object dataObject) { 
//    makeToast(MainActivity.this, "Right!"); 
      } 

      @Override 
      public void onAdapterAboutToEmpty(int itemsInAdapter) { 
       // Ask for more data here 
//    al = new ArrayList<>(); 
//    swipModel.setCardImageDrawable(uri); 
//    al.add(swipModel); 
      } 

      @Override 
      public void onScroll(float scrollProgressPercent) { 
       View view = flingContainer.getSelectedView(); 
      } 
     }); 


     // Optionally add an OnItemClickListener. 
     flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClicked(int itemPosition, Object dataObject) { 

      } 
     }); 
    }  
} 

đây là activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    tools:context="com.example.android.swipecardtesting.MainActivity"> 

    <com.lorentzos.flingswipe.SwipeFlingAdapterView 
     android:id="@+id/frame" 
     android:background="#ffeee9e2" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:rotation_degrees="15.5" 
     tools:context=".MyActivity" 
     android:layout_centerInParent="true" 
     /> 

</RelativeLayout> 

Đây là tôi Adapter

public class SwipViewAdapter extends BaseAdapter { 

    public static ArrayList<SwipModel> list; 
    Context context; 
    private LayoutInflater l_Inflater; 
    public static ViewHolder holder; 

    public SwipViewAdapter(Context mContext, ArrayList<SwipModel> al) { 
     this.context = mContext; 
     list = al; 
     l_Inflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     return list.size(); 
    } 

    @Override 
    public Object getItem(int i) { 
     return i; 
    } 

    @Override 
    public long getItemId(int i) { 
     return i; 
    } 

    @Override 
    public View getView(int i, View view, ViewGroup viewGroup) { 
     if (view == null) { 
      holder = new ViewHolder(); 

      l_Inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      view = l_Inflater.inflate(R.layout.swip_item, viewGroup, false); 


      holder.ivZoomable = (TouchImageView) view.findViewById(R.id.ivZoomable); 

      view.setTag(holder); 
     } 



     holder.ivZoomable.setImageURI(list.get(i).getCardImageDrawable()); 


     return view; 
    } 

    public static class ViewHolder { 
     public static TouchImageView ivZoomable; 
    } 
} 

TouchImageView lớp học của tôi

public class TouchImageView extends ImageView { 

    Matrix 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; 

    // Remember some things for zooming 
    PointF last = new PointF(); 
    PointF start = new PointF(); 
    float minScale = 1f; 
    float maxScale = 3f; 
    float[] m; 

    int viewWidth, viewHeight; 
    static final int CLICK = 3; 
    public static float saveScale = 1f; 
    protected float origWidth, origHeight; 
    int oldMeasuredWidth, oldMeasuredHeight; 

    ScaleGestureDetector mScaleDetector; 

    Context context; 

    public TouchImageView(Context context) { 
     super(context); 
     sharedConstructing(context); 
    } 

    public TouchImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     sharedConstructing(context); 
    } 

    private void sharedConstructing(Context context) { 
     super.setClickable(true); 
     this.context = context; 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
     matrix = new Matrix(); 
     m = new float[9]; 
     setImageMatrix(matrix); 
     setScaleType(ScaleType.MATRIX); 

     setOnTouchListener(new OnTouchListener() { 

      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       mScaleDetector.onTouchEvent(event); 
       PointF curr = new PointF(event.getX(), event.getY()); 

       switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
         last.set(curr); 
         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 fixTransX = getFixDragTrans(deltaX, viewWidth, 
            origWidth * saveScale); 
          float fixTransY = getFixDragTrans(deltaY, viewHeight, 
            origHeight * saveScale); 
          matrix.postTranslate(fixTransX, fixTransY); 
          fixTrans(); 
          last.set(curr.x, curr.y); 
         } 
         break; 

        case MotionEvent.ACTION_UP: 
         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) 
          performClick(); 
         break; 

        case MotionEvent.ACTION_POINTER_UP: 
         mode = NONE; 
         break; 
       } 

       setImageMatrix(matrix); 
       invalidate(); 
       return true; // indicate event was handled 
      } 

     }); 
    } 

    public void setMaxZoom(float x) { 
     maxScale = x; 
    } 


    private class ScaleListener extends 
      ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScaleBegin(ScaleGestureDetector detector) { 
      mode = ZOOM; 
      return true; 
     } 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      float mScaleFactor = detector.getScaleFactor(); 
      float origScale = saveScale; 
      saveScale *= mScaleFactor; 

      if(saveScale<1) 
      { 
       Log.e("saveScale is ","executing =====> "+saveScale); 
       SwipViewAdapter.ViewHolder.imageView.setVisibility(VISIBLE); 
       SwipViewAdapter.ViewHolder.ivZoomable.setVisibility(GONE); 
      } 
      else 
      { 
       Log.e("saveScale is ","executing =====> "+saveScale); 
       SwipViewAdapter.ViewHolder.imageView.setVisibility(GONE); 
       SwipViewAdapter.ViewHolder.ivZoomable.setVisibility(VISIBLE); 
      } 



      if (saveScale > maxScale) { 
       saveScale = maxScale; 
       mScaleFactor = maxScale/origScale; 
      } 
      else if (saveScale < minScale) { 
       saveScale = minScale; 
       mScaleFactor = minScale/origScale; 
      } 

      if (origWidth * saveScale <= viewWidth 
        || origHeight * saveScale <= viewHeight) 
       matrix.postScale(mScaleFactor, mScaleFactor, viewWidth/2, 
         viewHeight/2); 
      else 
       matrix.postScale(mScaleFactor, mScaleFactor, 
         detector.getFocusX(), detector.getFocusY()); 

      fixTrans(); 
      return true; 
     } 
    } 

    void fixTrans() { 
     matrix.getValues(m); 
     float transX = m[Matrix.MTRANS_X]; 
     float transY = m[Matrix.MTRANS_Y]; 

     float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale); 
     float fixTransY = getFixTrans(transY, viewHeight, origHeight 
       * saveScale); 

     if (fixTransX != 0 || fixTransY != 0) 
      matrix.postTranslate(fixTransX, fixTransY); 
    } 

    float getFixTrans(float trans, float viewSize, float contentSize) { 
     float minTrans, maxTrans; 

     if (contentSize <= viewSize) { 
      minTrans = 0; 
      maxTrans = viewSize - contentSize; 
     } else { 
      minTrans = viewSize - contentSize; 
      maxTrans = 0; 
     } 

     if (trans < minTrans) 
      return -trans + minTrans; 
     if (trans > maxTrans) 
      return -trans + maxTrans; 
     return 0; 
    } 

    float getFixDragTrans(float delta, float viewSize, float contentSize) { 
     if (contentSize <= viewSize) { 
      return 0; 
     } 
     return delta; 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     viewWidth = MeasureSpec.getSize(widthMeasureSpec); 
     viewHeight = MeasureSpec.getSize(heightMeasureSpec); 

     // 
     // Rescales image on rotation 
     // 
     if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight 
       || viewWidth == 0 || viewHeight == 0) 
      return; 
     oldMeasuredHeight = viewHeight; 
     oldMeasuredWidth = viewWidth; 

     if (saveScale == 1) { 
      // Fit to screen. 
      float scale; 

      Drawable drawable = getDrawable(); 
      if (drawable == null || drawable.getIntrinsicWidth() == 0 
        || drawable.getIntrinsicHeight() == 0) 
       return; 
      int bmWidth = drawable.getIntrinsicWidth(); 
      int bmHeight = drawable.getIntrinsicHeight(); 

      Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); 

      float scaleX = (float) viewWidth/(float) bmWidth; 
      float scaleY = (float) viewHeight/(float) bmHeight; 
      scale = Math.min(scaleX, scaleY); 
      matrix.setScale(scale, scale); 

      // Center the image 
      float redundantYSpace = (float) viewHeight 
        - (scale * (float) bmHeight); 
      float redundantXSpace = (float) viewWidth 
        - (scale * (float) bmWidth); 
      redundantYSpace /= (float) 2; 
      redundantXSpace /= (float) 2; 

      matrix.postTranslate(redundantXSpace, redundantYSpace); 

      origWidth = viewWidth - 2 * redundantXSpace; 
      origHeight = viewHeight - 2 * redundantYSpace; 
      setImageMatrix(matrix); 
     } 
     fixTrans(); 
    } 

} 
+0

có thể điều này giống như trợ giúp bạn: http://stackoverflow.com/questions/11672210/android-combine-swipe-and-pinch-to-zoom?rq=1 –

+0

@Abbas Cảm ơn bạn đã trả lời. Tôi đã thử như bạn nói nhưng vẫn không hoạt động. –

+0

Cố gắng trả lại 'false' từ' onTouch' nếu 'saveScale! = 1', thì sự kiện chạm phải được chuyển. – Divers

Trả lời

1

Return false trong OnTouchListener.onTouch() trong lớp TouchImageView khi chỉ có một con trỏ là xuống giống như vậy:

@Override 
public boolean onTouch(View v, MotionEvent event) { 

    // Touch logic here 

    return event.getPointerCount() > 1; 
} 

Bằng cách này pinch-to-zoom sẽ chỉ tiêu thụ sự kiện liên lạc khi hai con trỏ có mặt (cần thiết để thực hiện một nhúm với).

Cập nhật:

Mở rộng lớp SwipeFlingAdapterView và ghi đè lên các phương pháp onInterceptTouchEvent() như nó được thực hiện ở đây: Using onInterceptTouchEvent

Sau đó, bạn có thể đánh chặn các sự kiện liên lạc chuyển đến chế độ hình ảnh như thế này:

public void onInterceptTouchEvent(MotionEvent event) { 
    if(event.getPointerCount() == 1) { 
     onTouchEvent(event); 
    } 
    return false; 
} 

Tài liệu khác về các giao diện cảm ứng tại đây: https://developer.android.com/training/gestures/viewgroup.html

Hy vọng điều đó sẽ hữu ích!

+0

Cảm ơn bạn đã giúp tôi và tôi đặt mã của bạn trong touchImageView lớp onTouch nhưng vẫn còn chức năng swipe không làm việc chỉ pinch để phóng to là làm việc nhưng thực sự tôi cần pinch để phóng to cũng như chức năng swipe cũng. –

+0

Xem câu trả lời cập nhật của tôi – whitebrow

Các vấn đề liên quan