ImageView no escala en dispositivos de pantalla grande

Aquí está mi diseño básico:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ImageView android:adjustViewBounds="true" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/welcome_hero" /> </LinearLayout> 

Quiero que la imagen a escala, manteniendo la relación de aspecto para adaptarse a la pantalla, empujando las siguientes vistas hacia abajo.

Esto funciona muy bien en mi mdpi (LG LGP509) y hdpi (HTC G2, Nexus One) dispositivos. Sin embargo, en mi Galaxy Nexus (xhdpi), la imagen obstinadamente no escala para encajar. Deja espacio extra en los lados.

Aquí hay más información:

  • el diseño está en la distribución / carpeta genérica

  • welcome_hero.png está en la carpeta drawables / y tiene 320px de ancho y 161px de altura

AndroidManifest.xml tiene esta entrada:

 <uses-sdk android:targetSdkVersion="10" android:minSdkVersion="8" /> <supports-screens android:xlargeScreens="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="false" /> 

Algunas cosas que he intentado:

  • cambiar el scaleType a fitCenter, fitInside, o la matriz produjo los mismos resultados que sin
  • al cambiar la altura de ImageView a fill_parent, se ha escalado correctamente la imagen, pero se han eliminado todas las demás vistas
  • monitor amenazador con violencia física me dejó más frustrado
  • estableció explícitamente la altura y el ancho a 320dp y 161dp no cambió nada
  • como se mencionó anteriormente, He intentado nuevos diseños en el visor previo de IntelliJ y en dispositivos físicos

He estado pasando por StackOverflow durante aproximadamente 1,5 horas mirando los cientos de mensajes que parecen similares a los míos, pero ninguno parece hacer que las cosas funcionen en el Galaxy Nexus. Estoy tratando desesperadamente de ser un buen desarrollador y hacer mi escala de cosas a nuevos teléfonos, pero esto está resultando difícil.

Utilice una combinación de marcado de disposición y código para realizar la escala:

mantener su layout_width = "fill_parent" y layout_height = "wrap_content". Añadir

 android:scaleType="fitXY" 

En su código:

 ImageView mImageView = findViewById (R.id.yourimageid); LayoutParams lp = mImageView.getLayoutParams(); lp.height = (int)((float)context.getWindowManager().getDefaultDisplay().getWidth() * ((float)mImageView.getDrawable().getIntrinsicHeight() / (float)mImageView.getDrawable().getIntrinsicWidth())); mImageView.setLayoutParams(lp); 

es decir, está estableciendo un nuevo valor para layout_height multiplicando el ancho de pantalla * la relación de la altura de la imagen al ancho.

Es probable que desee establecer android:adjustViewBounds a true. Mantenga su ancho fill_parent y wrap_content altura. Es posible que todavía tenga que jugar con su scaleType para que funcione como se esperaba, aunque el aumento de escala tiende a ser complicado con este enfoque.

Otra opción es crear su propia subclase de ImageView. Lo siguiente ha funcionado bien para mí, pero puede necesitar alguna modificación para su caso específico.

 public class AspectRatioImageView extends ImageView { private final boolean horizontal; public AspectRatioImageView(Context context) { this(context, null); } public AspectRatioImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AspectRatioImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AspectRatioImageView, defStyle, 0); int h = array .getInt(R.styleable.AspectRatioImageView_fixedDimension, 0); horizontal = (h == 0); array.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { boolean widthExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; boolean heightExactly = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; float ratio; try { ratio = ((float) ((BitmapDrawable) getDrawable()) .getIntrinsicWidth()) / ((float) ((BitmapDrawable) getDrawable()) .getIntrinsicHeight()); } catch (ClassCastException e) { ratio = MeasureSpec.getSize(widthMeasureSpec) / MeasureSpec.getSize(heightMeasureSpec); } int heightRatioSpec = MeasureSpec.makeMeasureSpec( (int) (MeasureSpec.getSize(widthMeasureSpec) / ratio), MeasureSpec.EXACTLY); int widthRatioSpec = MeasureSpec.makeMeasureSpec( (int) (MeasureSpec.getSize(heightMeasureSpec) * ratio), MeasureSpec.EXACTLY); if (widthExactly) { if (heightExactly) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } else { super.onMeasure(widthMeasureSpec, heightRatioSpec); } } else { if (heightExactly) { super.onMeasure(widthRatioSpec, heightMeasureSpec); } else { if (horizontal) { super.onMeasure(widthMeasureSpec, heightRatioSpec); } else { super.onMeasure(widthRatioSpec, heightMeasureSpec); } } } } } 

También necesitará agregar

 <declare-styleable name="AspectRatioImageView"> <attr format="enum" name="fixedDimension"> <enum name="horizontal" value="0" /> <enum name="vertical" value="1" /> </attr> </declare-styleable> 

a tu /values/attr.xml para que puedas usar el atributo app:fixedDimension=horizontal para que sepa app:fixedDimension=horizontal escalar la dimensión vertical.

¿Quieres que tu vista se estire para ser tan ancha como la pantalla, y entonces, ¿qué altura se necesitaría para mantener la relación de aspecto original en ese ancho?

Creo que establecer un scaleType de centerInside hará que este trabajo. Centro de cultivo vale la pena intentar si dentro de centro no funciona. Vea: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

en lugar de usar android:src en su imageView XML , use android:background . Eso debería resolver los problemas de escala.

vea aquí: ¿Cuál es la diferencia entre src y el fondo de ImageView

  • Cargar imágenes en GridView con Universal Image Loader
  • SetShadowLayer provoca lento tiempo de dibujo en GridView?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.