English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Este artículo comparte el código específico de la demostración de efecto de escalado de la imagen superior en Android desplegable, a modo de ejemplo, el contenido específico es el siguiente
Efecto de la imagen
Análisis de efectos
1 Al deslizar hacia abajo, la imagen superior aumenta de tamaño constantemente con el deslizamiento del dedo
2 Deslizar hacia arriba, mover constantemente la imagen hacia arriba hasta que la imagen no sea visible
3 Al deslizar hacia arriba, cuando la imagen superior no es visible, deslizar hacia arriba ListView
Enfoque de implementación
1 Dado que esta vista se divide en dos partes superior e inferior, alineadas verticalmente, se puede implementar mediante la herencia de LinearLayout: personalizar un DragImageView, esta vista hereda de LinearLayout
public DragImageView(Context context, AttributeSet attrs) { super(context, attrs); // Por defecto, este View se alinea verticalmente setOrientation(LinearLayout.VERTICAL); // Usado para cooperar en el manejo del deslizamiento inercial de este View mScroller = new OverScroller(context); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mMaximumVelocity = ViewConfiguration.get(context) .getScaledMaximumFlingVelocity(); mMinimumVelocity = ViewConfiguration.get(context) .getScaledMinimumFlingVelocity(); }
2 Establecer la altura de la vista de contenido en onMeasure
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); LayoutParams params = (LayoutParams) getChildAt(1).getLayoutParams(); // La cabeza puede estar completamente oculta, por lo que la altura de la vista de contenido es igual a la altura del controlador params.height = getMeasuredHeight(); }
3 Configurar la propiedad ScaleType de ImageView
@Override protected void onFinishInflate() { super.onFinishInflate(); imageView = (ImageView) getChildAt(0); // Con el deslizamiento del dedo, la imagen se amplía continuamente (el ancho y el alto son mayores o iguales al tamaño de ImageView), y se muestra en el centro: // Basado en el análisis anterior, CENTER_CROP: se puede usar una escalada equilibrada de la imagen (mantener las proporciones originales de la imagen), para que las dos coordenadas (ancho, alto) de la imagen sean mayores o iguales a las coordenadas correspondientes de la vista (margen interno negativo), la imagen se colocará en el centro de la vista imageView.setScaleType(ScaleType.CENTER_CROP); listView = (ListView) getChildAt(1); }
4 Intercepción de eventos
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { downX = (int) ev.getX(); downY = (int) ev.getY(); } if (ev.getAction() == MotionEvent.ACTION_MOVE) { int currentX = (int) ev.getX(); int currentY = (int) ev.getY(); // Asegúrate de que sea un desplazamiento vertical if (Math.abs(currentY - downY) > Math.abs(currentX - downX)) { View childView = listView.getChildAt(listView .getFirstVisiblePosition()); // Hay dos situaciones que requieren interceptar: // 1 La imagen no está completamente oculta // 2 La imagen está completamente oculta, pero se desplaza hacia abajo y la ListView se desliza a la parte superior if (getScrollY() != imageHeight || (getScrollY() == imageHeight && currentY - downY > 0 && childView != null && childView.getTop() == 0)) { initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); return true; } } } if (ev.getAction() == MotionEvent.ACTION_UP) { recycleVelocityTracker(); } return super.onInterceptTouchEvent(ev); }
5 onTouchEvent ACTION_MOVE tratamiento
if (ev.getAction() == MotionEvent.ACTION_MOVE) { int currentX = (int) ev.getX(); int currentY = (int) ev.getY(); int deltyX = currentX - downX; int deltyY = currentY - downY; if (Math.abs(deltyY) > Math.abs(deltyX)) { if (deltyY > 0) { if (getScrollY() > 0) { if (getScrollY() - deltyY < 0) { scrollBy(0, -getScrollY()); return true; } // Cuando la imagen no se muestra completamente y se desplaza hacia abajo, continuar con toda la vista para que la imagen sea visible scrollBy(0, -deltyY); } else { // Cuando la imagen se muestra completamente y se desplaza hacia abajo, se amplía continuamente la imagen (cambiando la altura de ImageView) LayoutParams layoutParams = (LayoutParams) getChildAt(0) .getLayoutParams(); layoutParams.height = layoutParams.height + deltyY / 2; getChildAt(0).setLayoutParams(layoutParams); } } else { // Cuando la imagen aún está en estado de ampliación y se desliza hacia arriba, seguir reduciendo continuamente la altura de la imagen para que la imagen se reduzca if (getChildAt(1).getTop() > imageHeight) { LayoutParams layoutParams = (LayoutParams) getChildAt(0) .getLayoutParams(); layoutParams.height = layoutParams.height + deltyY / 2; getChildAt(0).setLayoutParams(layoutParams); } else { // Cuando la imagen está en estado normal y se desliza hacia arriba, mover toda la View y reducir el rango visible de la imagen if (getScrollY() - deltyY > imageHeight) { scrollBy(0, imageHeight - getScrollY()); return true; } scrollBy(0, -deltyY); } } downY = currentY; downX = currentX; return true; } }
6 Manejo de ACTION_UP en onTouchEvent
if (ev.getAction() == MotionEvent.ACTION_UP) { // Al soltar la imagen mientras está en estado de ampliación, hacer que la imagen se reduzca lentamente a su estado original if (getChildAt(1).getTop() > imageHeight) { isAnimating = true; ValueAnimator valueAnimator = ValueAnimator.ofInt(getChildAt(1) .getTop(), imageHeight); valueAnimator.setDuration(300); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (Integer) animation.getAnimatedValue(); LayoutParams layoutParams = (LayoutParams) getChildAt(0) .getLayoutParams(); layoutParams.height = value; getChildAt(0).setLayoutParams(layoutParams); } }); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) {}} super.onAnimationEnd(animation); isAnimating = false; } }); valueAnimator.start(); } // Cuando la imagen está en estado normal y no está completamente oculta, y el deslizamiento al soltar es mayor que el valor mínimo de deslizamiento inercial permitido, permita que View genere un efecto de deslizamiento inercial if (getChildAt(1).getTop() == imageHeight && getScrollY() != imageHeight) { mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityY = (int) mVelocityTracker.getYVelocity(); if (Math.abs(velocityY) > mMinimumVelocity) { fling(-velocityY); } recycleVelocityTracker(); }
Resumen
Aquí hay dos puntos de aprendizaje principales
1 Manejo de la ampliación de imágenes, interceptación de eventos
2 Deslizamiento inercial de View: se combina principalmente con el uso de OverScroller
Esto es todo el contenido del artículo, espero que sea útil para su aprendizaje y que apoyen más al tutorial de grito.
Declaración: El contenido de este artículo se ha obtenido de la red, es propiedad del autor original, el contenido se ha proporcionado y subido de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no ha sido editado por humanos y no asume responsabilidad alguna por las responsabilidades legales. Si encuentra contenido sospechoso de copyright, le invitamos a enviar un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.