Android:缩放可绘制或背景图片?

在布局上,我想将背景图像(保持其高宽比)缩放到创build页面时分配的空间。 任何人有任何想法如何做到这一点?

我正在使用layout.setBackgroundDrawable()和使用BitmapDrawable setGravity剪辑和填充,但没有看到任何缩放选项。

要自定义背景图像缩放,请创build如下资源:

<?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" /> 

然后,如果用作背景,它将在视图中居中。 还有其他标志: http : //developer.android.com/guide/topics/resources/drawable-resource.html

还没有试图做你想要的,但你可以缩放一个ImageView使用android:scaleType="fitXY"
它将被resize以适应您给ImageView的任何大小。

因此,您可以为您的布局创build一个FrameLayout,将ImageView放入其中,然后在FrameLayout中使用其他任何需要的内容以及透明背景。

 <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> 

有一个简单的方法可以从drawable中做到这一点:

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> 

唯一的缺点是,如果没有足够的空间,你的图像将不会被完全显示出来,但是它会被剪切掉,我找不到一个可以直接从drawable中做到这一点的方法。 但是从testing中我发现它工作得很好,而且不会剪切太多的图像。 你可以玩更多的重力选项。

另一种方法是创build一个布局,在那里你将使用ImageView并将scaleType设置为fitCenter

要保持高宽比,您必须使用android:scaleType=fitCenterfitStart等。使用fitXY将不会保持图像的原始高宽比!

请注意,这仅适用于具有src属性的图像,而不适用于背景图像。

使用图像作为背景大小布局:

 <?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> 

当您使用setBackgroundDrawable方法设置ImageView的Drawable时,图像将始终被缩放。 adjustViewBounds或不同的ScaleTypes参数将被忽略。 保持宽高比的唯一解决scheme是在加载绘图后调整ImageView大小。 这里是我使用的代码片段:

 // 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); 

在上面的代码片段中, bmp是要显示的Bitmap对象,而imageViewImageView对象

重要的是要注意布局参数的变化 。 这是必要的,因为setMaxHeightsetMaxWidth只有在定义宽度和高度来包装内容时才会有所作为,而不是填充父项。 另一方面,填充父项是开始时所需的设置,因为否则, containerWidthcontainerHeight值都等于0.所以,在你的布局文件中,你的ImageView中会有这样的内容:

 ... <ImageView android:id="@+id/my_image_view" android:layout_width="fill_parent" android:layout_height="fill_parent"/> ... 

这不是最高性能的解决scheme,但作为有人build议,而不是背景,你可以创buildFrameLayout或RelativeLayout,并使用ImageView作为伪背景 – 其他元素将位置简单地上面:

 <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> 

ImageView的问题是,只有可用的scaleType是:CENTER,CENTER_CROP,CENTER_INSIDE,FIT_CENTER,FIT_END,FIT_START,FIT_XY,MATRIX( http://etcodehome.blogspot.de/2011/05/android-imageview-scaletype-samples.html

并且在某些情况下“缩放背景图像(保持其高宽比)”,当想要图像填满整个屏幕(例如背景图像)并且屏幕的高宽比与图像的宽高比不同时,必要的scaleType是kind TOP_CROP,因为:

CENTER_CROP以缩放的图像为中心,而不是将图像上边缘与图像视图的上边缘alignment,并且FIT_START适合屏幕高度,而不是填充宽度。 正如用户Anke注意到FIT_XY不保持宽高比。

很高兴有人扩展ImageView来支持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://stackoverflow.com/a/14815588/2075875

现在恕我直言,将是完美的,如果有人写了自定义可缩放图像像这样的绘图。 然后它可以被用作背景参数。


Reflogbuild议在使用前预先绘制drawable。 这里是说明如何做到这一点: Java(Android):如何在没有Bitmap的情况下绘制drawable? 虽然它有缺点,但是可缩放的drawable / bitmap会使用更多的RAM,而ImageView使用的缩放并不需要更多的内存。 好处可能是更less的处理器负载。

Dweebo提出的工作。 但在我看来,这是没有必要的。 一个可绘制的背景本身可以很好地扩展。 视图应该具有固定的宽度和高度,如下例所示:

  < 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> 

下面的代码完全使用相同大小的图像视图。 获取位图图像的高度和宽度,然后借助imageview的参数计算新的高度和宽度。 这给你所需的图像与最佳的长宽比。

 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) 

要尝试的一个select是将图像放在drawable-nodpi文件夹中,并将布局的背景设置为可绘制的资源ID。

这绝对适用于缩小,但我还没有扩大testing。

在将其用作背景之前,您必须预先绘制该drawable

您可以使用下列之一:

机器人:重力= “fill_horizo​​ntal | clip_vertical”

要么

机器人:重力= “fill_vertical | clip_horizo​​ntal”