android - studio - tamaño de imagen para fondo de pantalla para celular
Android: ¿Escalar una imagen extraíble o de fondo? (12)
En un diseño, quiero escalar la imagen de fondo (manteniendo su relación de aspecto) al espacio asignado cuando se crea la página. Alguien tiene alguna idea de cómo hacer esto?
Estoy usando layout.setBackgroundDrawable () y estoy usando BitmapDrawable para establecer Gravedad para el recorte y el llenado, pero no veo ninguna opción para escalar.
Cuando configura el Drawable de un ImageView utilizando el método setBackgroundDrawable
, la imagen siempre se escalará. Se adjustViewBounds
parámetros como adjustViewBounds
o adjustViewBounds
diferentes. La única solución para mantener la relación de aspecto que encontré, es cambiar el tamaño de ImageView
después de cargar su dibujable. Aquí está el fragmento de código que utilicé:
// bmp is your Bitmap object
int imgHeight = bmp.getHeight();
int imgWidth = bmp.getWidth();
int containerHeight = imageView.getHeight();
int containerWidth = imageView.getWidth();
boolean ch2cw = containerHeight > containerWidth;
float h2w = (float) imgHeight / (float) imgWidth;
float newContainerHeight, newContainerWidth;
if (h2w > 1) {
// height is greater than width
if (ch2cw) {
newContainerWidth = (float) containerWidth;
newContainerHeight = newContainerWidth * h2w;
} else {
newContainerHeight = (float) containerHeight;
newContainerWidth = newContainerHeight / h2w;
}
} else {
// width is greater than height
if (ch2cw) {
newContainerWidth = (float) containerWidth;
newContainerHeight = newContainerWidth / h2w;
} else {
newContainerWidth = (float) containerHeight;
newContainerHeight = newContainerWidth * h2w;
}
}
Bitmap copy = Bitmap.createScaledBitmap(bmp, (int) newContainerWidth, (int) newContainerHeight, false);
imageView.setBackgroundDrawable(new BitmapDrawable(copy));
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
imageView.setLayoutParams(params);
imageView.setMaxHeight((int) newContainerHeight);
imageView.setMaxWidth((int) newContainerWidth);
En el fragmento de código de arriba está bmp el objeto de mapa de bits que se va a mostrar y el objeto ImageView
es el objeto ImageView
Una cosa importante a tener en cuenta es el cambio de los parámetros de diseño . Esto es necesario porque setMaxHeight
y setMaxWidth
solo marcarán la diferencia si el ancho y alto están definidos para envolver el contenido, no para llenar el elemento principal. Fill parent por otro lado es la configuración deseada al principio, porque de lo contrario containerWidth
y containerHeight
tendrán valores equivalentes a 0. Por lo tanto, en su archivo de diseño tendrá algo como esto para su ImageView:
...
<ImageView android:id="@+id/my_image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
...
El código Abajo hace que el mapa de bits se ajuste perfectamente al mismo tamaño de la vista de la imagen. Obtenga la altura y el ancho de la imagen de mapa de bits y luego calcule la nueva altura y ancho con la ayuda de los parámetros de la vista de imagen. Eso le da la imagen requerida con la mejor relación de aspecto.
int bwidth=bitMap1.getWidth();
int bheight=bitMap1.getHeight();
int swidth=imageView_location.getWidth();
int sheight=imageView_location.getHeight();
new_width=swidth;
new_height = (int) Math.floor((double) bheight *( (double) new_width / (double) bwidth));
Bitmap newbitMap = Bitmap.createScaledBitmap(bitMap1,new_width,new_height, true);
imageView_location.setImageBitmap(newbitMap)
Esta no es la solución más eficaz, pero como alguien sugirió en lugar de fondo, puede crear FrameLayout o RelativeLayout y usar ImageView como pseudo fondo; otros elementos se colocarán simplemente encima de él:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/ivBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitStart"
android:src="@drawable/menu_icon_exit" />
<Button
android:id="@+id/bSomeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="61dp"
android:layout_marginTop="122dp"
android:text="Button" />
</RelativeLayout>
El problema con ImageView es que solo los scaleTypes disponibles son: CENTER, CENTRE_CROP, CENTER_INSIDE, FIT_CENTER, FIT_END, FIT_START, FIT_XY, MATRIX ( http://etcodehome.blogspot.de/2011/05/android-imageview-scaletype-samples.html )
y para "escalar la imagen de fondo (manteniendo su relación de aspecto)" en algunos casos, cuando desea que una imagen ocupe toda la pantalla (por ejemplo, imagen de fondo) y la relación de aspecto de la pantalla es diferente a la imagen, el tipo de escala necesario es amable de TOP_CROP, porque:
CENTER_CROP centra la imagen escalada en lugar de alinear el borde superior con el borde superior de la vista de la imagen y FIT_START ajusta la altura de la pantalla y no completa el ancho. Y como el usuario Anke notó que FIT_XY no mantiene la relación de aspecto.
Con mucho gusto, alguien ha ampliado ImageView para admitir TOP_CROP
public class ImageViewScaleTypeTopCrop extends ImageView {
public ImageViewScaleTypeTopCrop(Context context) {
super(context);
setup();
}
public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
private void setup() {
setScaleType(ScaleType.MATRIX);
}
@Override
protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {
float frameWidth = frameRight - frameLeft;
float frameHeight = frameBottom - frameTop;
if (getDrawable() != null) {
Matrix matrix = getImageMatrix();
float scaleFactor, scaleFactorWidth, scaleFactorHeight;
scaleFactorWidth = (float) frameWidth / (float) getDrawable().getIntrinsicWidth();
scaleFactorHeight = (float) frameHeight / (float) getDrawable().getIntrinsicHeight();
if (scaleFactorHeight > scaleFactorWidth) {
scaleFactor = scaleFactorHeight;
} else {
scaleFactor = scaleFactorWidth;
}
matrix.setScale(scaleFactor, scaleFactor, 0, 0);
setImageMatrix(matrix);
}
return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
}
}
https://.com/a/14815588/2075875
Ahora, en mi humilde opinión, sería perfecto si alguien escribiera Drawable personalizado que escale una imagen como esa. Entonces podría usarse como parámetro de fondo.
Reflog sugiere preescalar drawable antes de usarlo. Aquí hay instrucciones de cómo hacerlo: Java (Android): ¿Cómo escalar un dibujable sin Bitmap? Aunque tiene una desventaja, ese mapa escalable / dibujable de escala mayor usará más RAM, mientras que el escalado sobre la marcha utilizado por ImageView no requiere más memoria. La ventaja podría ser menos carga del procesador.
Hay una manera fácil de hacer esto desde el dibujable:
your_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@color/bg_color"/>
<item>
<bitmap
android:gravity="center|bottom|clip_vertical"
android:src="@drawable/your_image" />
</item>
</layer-list>
El único inconveniente es que si no hay suficiente espacio, su imagen no se mostrará completamente, pero se recortará, no pude encontrar una manera de hacerlo directamente desde un dibujante. Pero de las pruebas que hice funciona bastante bien, y no recorta gran parte de la imagen. Podrías jugar más con las opciones de gravedad.
Otra forma será simplemente crear un diseño, donde usará un ImageView
y establecerá el scaleType
en fitCenter
.
Lo que Dweebo propuso funciona. Pero en mi humilde opinión, es innecesario. Un fondo dibujable se escala bien por sí mismo. La vista debe tener ancho y alto fijos, como en el siguiente ejemplo:
< RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/black">
<LinearLayout
android:layout_width="500dip"
android:layout_height="450dip"
android:layout_centerInParent="true"
android:background="@drawable/my_drawable"
android:orientation="vertical"
android:padding="30dip"
>
...
</LinearLayout>
< / RelativeLayout>
No has intentado hacer exactamente lo que quieres, pero puedes escalar un ImageView usando android:scaleType="fitXY"
y se dimensionará para adaptarse al tamaño que le des a ImageView.
Por lo tanto, podría crear un FrameLayout para su diseño, colocar ImageView dentro de él y, luego, cualquier otro contenido que necesite en FrameLayout con un fondo transparente.
<FrameLayout
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:src="@drawable/back" android:scaleType="fitXY" />
<LinearLayout>your views</LinearLayout>
</FrameLayout>
Para mantener la relación de aspecto, debe usar android:scaleType=fitCenter
o fitStart
etc. ¡El uso de fitXY
no mantendrá la relación de aspecto original de la imagen!
Tenga en cuenta que esto solo funciona para imágenes con un atributo src
, no para la imagen de fondo.
Para personalizar la escala de la imagen de fondo crea un recurso como este:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:src="@drawable/list_bkgnd" />
Luego se centrará en la vista si se usa como fondo. También hay otros indicadores: http://developer.android.com/guide/topics/resources/drawable-resource.html
Puedes usar uno de los siguientes:
android: gravity = "fill_horizontal | clip_vertical"
O
android: gravedad = "fill_vertical | clip_horizontal"
Tendrás que escalar previamente ese dibujo antes de usarlo como fondo
Una opción para intentar es poner la imagen en la carpeta drawable-nodpi
y establecer el fondo de un diseño en la id del recurso dibujable.
Esto definitivamente funciona con la reducción de escala, aunque no he probado con la ampliación.
Utilice la imagen como fondo de tamaño para el diseño:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/imgPlaylistItemBg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:maxHeight="0dp"
android:scaleType="fitXY"
android:src="@drawable/img_dsh" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</FrameLayout>