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.
- SetShadowLayer provoca lento tiempo de dibujo en GridView?
- Controlar la visibilidad de la vista desde un recurso
- ImageView dentro de RelativeLayout tiene relleno superior e inferior
- Rotación a un ImageView, dentro de un RelativeLayout
- Relleno de ScrollView
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.
- Establecer una imagen en el elemento ListView utilizando SimpleCursorAdapter y ViewBinder
- Cómo reasignar una imagen de 9 parches mediante programación a un ImageView?
- Creación de una vista de imagen dibujable y zoomable en android
- Cómo saber si Ver dentro de Desplazamiento es visible completamente o no
- Cargar imágenes en GridView con Universal Image Loader
- Cuando es necesario ejecutar invalidate () en una vista?
- Diferencia entre setAlpha y setImageAlpha
- Vista de imagen de Android Autoscroll
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