Android салфетки карт с щепоткой для увеличения изображения с помощью SwipeFlingAdapterView библиотеки

Я использую swipe card с функцией pinch to zoom с использованием этой библиотеки, и когда я использую только представление image view то она отлично работает, это означает, что мы хорошо работаем, но я хочу использовать салфетки, такие как библиотека, а также pinch to zoom поэтому я добавил класс TouchImageView в котором только pinch to zoom работы, но функция прокрутки не работает. Не могли бы вы помочь мне решить эту проблему или предложить мне какую-либо альтернативную библиотеку, в которой можно использовать swipe card и pinch to zoom . Ниже моя деятельность

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

Здесь 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> 

Вот мой 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

 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(); } } 

    Возвращает false в OnTouchListener.onTouch() в классе TouchImageView когда только один указатель опущен так:

     @Override public boolean onTouch(View v, MotionEvent event) { // Touch logic here return event.getPointerCount() > 1; } 

    Таким образом, пинч-к-зум будет потреблять только событие касания, когда присутствуют два указателя (необходимо выполнить щепотку).

    Обновить:

    Расширьте класс SwipeFlingAdapterView и переопределите метод onInterceptTouchEvent() как это делается здесь: Использование onInterceptTouchEvent

    Затем вы можете перехватить событие касания, направленное к представлению изображения следующим образом:

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

    Более подробная информация о сенсорных перехватах здесь: https://developer.android.com/training/gestures/viewgroup.html

    Надеюсь, поможет!