Problema con CoordinatorLayout y ImageView que ajusta el ancho mientras se desplaza

Estoy intentando poner un ImageView en un CollapsingToolbarLayout en el cual toma la pantalla llena en carga y como usted rueda el contenido, el ancho de la imagen de la resolución 16×9 vuelve a clasificar según el tamaño hasta que la imagen ocupa el ancho completo de la pantalla. En ese momento, me gustaría que la imagen de paralaje con una app:layout_collapseParallaxMultiplier de 0,5

Uso de este diseño XML:

 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/img_hero" android:layout_width="match_parent" android:layout_height="match_parent" android:adjustViewBounds="true" android:scaleType="centerCrop" android:src="@drawable/lake" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.5"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="none" app:popupTheme="@style/AppTheme.PopupOverlay"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_scrolling"/> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/fab_margin" app:layout_anchor="@id/app_bar" app:layout_anchorGravity="bottom|end" app:srcCompat="@android:drawable/ic_dialog_email"/> </android.support.design.widget.CoordinatorLayout> 

Realiza lo siguiente:

Introduzca aquí la descripción de la imagen

Cuál de los siguientes muestra cuáles son los límites reales de la imagen:

Introduzca aquí la descripción de la imagen

A medida que me desplazo, me gustaría más del ancho de la imagen para mostrar como la altura de la imagen se contrae y los resultados en lo siguiente:

Introduzca aquí la descripción de la imagen

Una vez que llego a este punto, aquí es donde me gustaría que el multiplicador de paralaje colapso de 0,5 para tener efecto.

He ensuciado con muchos comportamientos de desplazamiento diferentes, probado todos los scrollTypes ImageView , sin éxito. ¿Alguien sabe si esto es posible y si es así, puede proporcionar cualquier indicación en lo que estoy haciendo mal o no haciendo.

¿Necesito crear mi propio CoordinatorLayout.Behavior personalizado para lograr esto?

One Solution collect form web for “Problema con CoordinatorLayout y ImageView que ajusta el ancho mientras se desplaza”

Puede lograr lo que desea mediante el seguimiento de desplazamiento vertical de AppBarLayout . Tiene método hermoso addOnOffsetChangedListener , así que usted puede escalar su imagen dependiendo de la compensación de AppBarLayout .

Por lo tanto, hay tres cosas que usted tiene que hacer para conseguir que funcione:

  1. drawable-nodpi colocar su imagen en drawable-nodpi carpeta drawable-nodpi , para evitar que Android la escalen para diferentes tamaños de pantalla.
  2. Cambie el scaleType propiedad de scaleType a la matrix – es necesario ya que cambiaremos la matriz de este ImageView por nosotros mismos.
  3. Implemente addOnOffsetChangedListener para usted AppBarLayout de la siguiente manera:

     final ImageView imageView = (ImageView) findViewById(R.id.img_hero); AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.app_bar); appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { Matrix matrix = new Matrix(imageView.getImageMatrix()); //get image's width and height final int dwidth = imageView.getDrawable().getIntrinsicWidth(); final int dheight = imageView.getDrawable().getIntrinsicHeight(); //get view's width and height final int vwidth = imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight(); int vheight = imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom(); float scale; float dx = 0, dy = 0; float parallaxMultiplier = ((CollapsingToolbarLayout.LayoutParams) imageView.getLayoutParams()).getParallaxMultiplier(); //maintain the image's aspect ratio depending on offset if (dwidth * vheight > vwidth * dheight) { vheight += (verticalOffset); //calculate view height depending on offset scale = (float) vheight / (float) dheight; //calculate scale dx = (vwidth - dwidth * scale) * 0.5f; //calculate x value of the center point of scaled drawable dy = -verticalOffset * (1 - parallaxMultiplier); //calculate y value by compensating parallaxMultiplier } else { scale = (float) vwidth / (float) dwidth; dy = (vheight - dheight * scale) * 0.5f; } int currentWidth = Math.round(scale * dwidth); //calculate current intrinsic width of the drawable if (vwidth <= currentWidth) { //compare view width and drawable width to decide, should we scale more or not matrix.setScale(scale, scale); matrix.postTranslate(Math.round(dx), Math.round(dy)); imageView.setImageMatrix(matrix); } } }); 

Lo que hice aquí es obtener el código fuente de ImageView para determinar los límites cuando tiene tipo de escala centerCrop y luego calcular la escala y la traducción de la matriz dependiendo de verticalOffset . Si el valor de la escala es menor que 1.0f, hemos llegado al punto en el que la relación de aspecto de nuestra vista es igual a la relación de aspecto del dibujable y no necesitamos escalar más.

Nota :

  1. Funcionaría como usted desea, solamente con la imagen cuyo width> height, si no su comportamiento sería igual que centerCrop
  2. Funcionaría sólo si tu parallaxMultiplier está entre 0 y 1.

Cómo me busca:

Introduzca aquí la descripción de la imagen

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.