2016-09-03 14 views
8

Jestem wykonawczych swipe card z pinch to zoom funkcjonalności za pomocą this bibliotekę i kiedy używać tylko image view to działa dobrze środki przesuń pracę prawidłowo, ale chcę funkcjonalność bezstykowa jak biblioteki, jak również pinch to zoom więc Dodałem klasę TouchImageView, w której działa tylko pinch to zoom, ale funkcja przesunięcia nie działa. Czy mógłbyś mi pomóc rozwiązać ten problem lub zasugerować mi alternatywną bibliotekę, w której możliwe są swipe card i pinch to zoom. Poniżej jest moja aktywnośćAndroid karta bezstykowa z pinch to zoom ImageView użyciu SwipeFlingAdapterView bibliotekę

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) { 

      } 
     }); 
    }  
} 

tutaj jest 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> 

Oto mój 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; 
    } 
} 

i mój TouchImageView klasa

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

może to pomóc: http://stackoverflow.com/questions/11672210/android-combine-swipe-and-pinch-to-zoom?rq=1 –

+0

@Abbas Dzięki za odpowiedź. Próbowałem, jak powiedziałeś, ale wciąż nie działa. –

+0

Spróbuj zwrócić 'false' z' onTouch', jeśli 'saveScale! = 1', wtedy zdarzenie dotyku powinno zostać przekazane. – Divers

Odpowiedz

1

Powrót false w OnTouchListener.onTouch() w klasie TouchImageView gdy tylko jeden wskaźnik nie działa tak:

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

    // Touch logic here 

    return event.getPointerCount() > 1; 
} 

ten sposób pinch-to-zoom będzie tylko zużywają dotykowy zdarzenie, kiedy dwa wskaźniki są obecne (niezbędne do wykonywania szczyptę z).

Aktualizacja:

rozszerzyć klasę SwipeFlingAdapterView i zastąpić metodę onInterceptTouchEvent() jak to zrobić tutaj: Using onInterceptTouchEvent

Następnie można przechwycić dotykowy imprezę skierowaną do widoku obrazu tak:

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

Więcej informacji na temat przechwytywania dotykowego tutaj: https://developer.android.com/training/gestures/viewgroup.html

Mam nadzieję, że pomoże!

+0

Dziękuję za pomoc, a ja wstawiam twój kod do onTouch klasy TouchImageView, ale funkcja "swipe" wciąż działa nie tylko szczypta, aby zoom działał, ale tak naprawdę potrzebuję szczypania do powiększania, a także funkcji przesuwania. –

+0

Sprawdź moją zaktualizowaną odpowiedź – whitebrow