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
- Cómo obtener el estado de la casilla de verificación en el listview expandible en android
- Grupo de escucha de clics en la vista de lista ampliable de android
- Cabezal / artículo pegajoso en la vista de reciclaje
- ImageButton en el elemento secundario de lista expandible
- Android ExpandableListView y onChildClick no funciona
<?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(); } }
- ¿Cómo comprobar si una viewStub ya está inflada?
- Cómo reproducir video en VideoView dentro de ViewPager desde el servidor
- Cómo mostrar el contenido web en iOS y Android mediante QML
- Android: en el interruptor de desplazamiento entre Vistas / Actividades / Fragmentos
- Android: Agregar vista dinámicamente en un diseño anidado
- cargar pdf desde url en android
- Cómo usar una misma fontface personalizada para toda la vista en android?
- Cómo pasar un valor de cadena a webView de una actividad
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!
- MultiViewPager + ZoomOutPageTransformer no funciona correctamente
- No se puede realizar esta acción después de onSaveInstanceState (onClick preference)