在布局上,我想将背景图像(保持其纵横比)缩放到创建页面时分配的空间。任何人都知道如何做到这一点?
我正在使用layout.setBackgroundDrawable()并使用BitmapDrawable来设置剪裁和填充的权限,但是没有看到任何缩放选项。
答案 0 :(得分:86)
要自定义背景图像缩放,请创建如下资源:
<?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
答案 1 :(得分:53)
没有尝试完全按照您的意愿行事,但您可以使用android:scaleType="fitXY"
来缩放ImageView
并且它的大小将适合您为ImageView提供的任何大小。
所以你可以为你的布局创建一个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>
答案 2 :(得分:28)
有一种简单的方法可以从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中做到这一点的方法。但是从我做过的测试来看,它的效果非常好,而且它并没有削减那么多的图像。您可以使用重力选项进行更多操作。
另一种方法是创建一个布局,您将使用 ImageView
并将 scaleType
设置为 { {1}} 强>
答案 3 :(得分:17)
要保持宽高比,您必须使用android:scaleType=fitCenter
或fitStart
等。使用fitXY
将无法保持图像的原始宽高比!
请注意,这仅适用于具有src
属性的图像,而不适用于背景图像。
答案 4 :(得分:15)
使用图片作为布局背景大小:
<?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>
答案 5 :(得分:5)
使用setBackgroundDrawable
方法设置ImageView的Drawable时,图像将始终缩放。作为adjustViewBounds
或不同ScaleTypes
的参数将被忽略。保持我找到的宽高比的唯一解决方案是在加载drawable后调整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对象, imageView 是ImageView
对象
需要注意的一个重要事项是更改布局参数。这是必要的,因为setMaxHeight
和setMaxWidth
只会在定义宽度和高度以包装内容时产生差异,而不是填充父级。另一方面,填充父级是开头所需的设置,因为否则containerWidth
和containerHeight
都将具有等于0的值。
因此,在您的布局文件中,您将为ImageView提供类似的内容:
...
<ImageView android:id="@+id/my_image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
...
答案 6 :(得分:4)
这不是最高性能的解决方案,但正如有人建议而不是背景你可以创建FrameLayout或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的问题是只有scaleTypes可用: 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是一种TOP_CROP,因为:
CENTER_CROP使缩放图像居中,而不是将顶边与图像视图的上边缘对齐,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
如果有人写了自定义Drawable,那么恕我直言就会很完美。然后它可以用作背景参数。
Reflog建议在使用之前预先缩放drawable。以下是如何操作的说明: Java (Android): How to scale a drawable without Bitmap? 虽然它有缺点,但升级的drawable / bitmap将使用更多的RAM,而ImageView使用的即时扩展不需要更多的内存。优势可能是处理器负载减少。
答案 7 :(得分:4)
下面的代码使得位图与imageview的大小完全相同。获取位图图像的高度和宽度,然后借助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)
答案 8 :(得分:2)
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>
答案 9 :(得分:0)
尝试的一个选项是将图像放在drawable-nodpi
文件夹中,并将布局的背景设置为可绘制的资源ID。
这绝对适用于缩小,但我还没有通过扩展测试。
答案 10 :(得分:0)
科特琳:
如果您需要在View中绘制位图,请缩放为FIT。
在bm宽高比小于容器宽高比的情况下,您可以进行适当的计算以将bm的高度设置为等于容器的高度并调整宽度,或者在相反的情况下为相反的值。
图片:
// binding.fragPhotoEditDrawCont is the RelativeLayout where is your view
// bm is the Bitmap
val ch = binding.fragPhotoEditDrawCont.height
val cw = binding.fragPhotoEditDrawCont.width
val bh = bm.height
val bw = bm.width
val rc = cw.toFloat() / ch.toFloat()
val rb = bw.toFloat() / bh.toFloat()
if (rb < rc) {
// Bitmap Width to Height ratio is less than Container ratio
// Means, bitmap should pin top and bottom, and have some space on sides.
// _____ ___
// container = |_____| bm = |___|
val bmHeight = ch - 4 //4 for container border
val bmWidth = rb * bmHeight //new width is bm_ratio * bm_height
binding.fragPhotoEditDraw.layoutParams = RelativeLayout.LayoutParams(bmWidth.toInt(), bmHeight)
}
else {
val bmWidth = cw - 4 //4 for container border
val bmHeight = 1f/rb * cw
binding.fragPhotoEditDraw.layoutParams = RelativeLayout.LayoutParams(bmWidth, bmHeight.toInt())
}
答案 11 :(得分:-4)
在将其用作背景之前,您必须预先缩放该绘图
答案 12 :(得分:-5)
您可以使用以下方法之一:
机器人:比重=&#34; fill_horizontal | clip_vertical&#34;
或者
机器人:比重=&#34; fill_vertical | clip_horizontal&#34;