Android deslizar la tarjeta con una pizca para ampliar la vista de la imagen con SwipeFlingAdapterView biblioteca

Estoy implementando la swipe card con pinch to zoom funcionalidad utilizando esta biblioteca y cuando uso sólo la image view continuación, trabajar bien significa deslizar el trabajo correctamente, pero quiero swipe funcionalidad como biblioteca, así como pinch to zoom así que agregó TouchImageView clase en la que sólo pinch to zoom pero la funcionalidad deslizar no está funcionando. Así que por favor, podría ayudarme a resolver este problema o sugerirme cualquier biblioteca alternativa en la que la swipe card y pinch to zoom es posible. A continuación se muestra mi actividad

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

Aquí es 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> 

Aquí está mi 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; } } 

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

Devuelve false en OnTouchListener.onTouch() en la clase TouchImageView cuando sólo hay un puntero abajo como así:

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

De esta manera pellizcar-a-zoom sólo consumirá el evento táctil cuando dos punteros están presentes (necesario para realizar una pizca con).

Actualizar:

Amplíe la clase SwipeFlingAdapterView y anule el método onInterceptTouchEvent() como se hace aquí: Using onInterceptTouchEvent

A continuación, puede interceptar el evento táctil dirigido a la vista de imagen de la siguiente manera:

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

Más documentación sobre intercepciones táctiles aquí: https://developer.android.com/training/gestures/viewgroup.html

¡Espero eso ayude!

  • Android define la altura y el ancho de Vista personalizada mediante programación
  • Vista dinámica con desplazamiento horizontal y vertical
  • LAYER_TYPE_SOFTWARE causa que WebView cargue la página en blanco
  • ¿Cómo mostrar la lista desplegable-ver debajo de la vista particular en android?
  • Cómo obtener la posición de View en onCreateViewHolder
  • Obtener Vista para el elemento ListView / orden inversa en 2.2; Funciona en 4.0.3
  • ExpandableListView con arrastrar y soltar de elementos de la lista en Android
  • cómo guardar y restaurar Webview Estado?
  • Android: Obtener una vista Referencia a un elemento de menú
  • WebView de Android - Dithering / Cambios al tacto
  • Detecta qué vista se desliza el dedo en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.