缩放图像保持其纵横比在后台可绘制

如何使背景图像适合视图,但使用<bitmap />作为背景可绘制xml时保持其纵横比? 没有<bitmap>android:gravity值给出了所需的效果。

只能在xml文件中操作背景属性是不可能的。 有两个选项:

  1. 使用Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)以编程方式剪切/缩放位Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)并将其设置为某个View的背景。

  2. 您使用ImageView而不是将背景放置为第一个布局的元素,并android:scaleType指定android:scaleType属性:

     <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/backgrnd" android:scaleType="centerCrop" /> ... rest layout components here ... </RelativeLayout> 

有一个简单的方法可以从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

希望这些信息可以帮助你实现你想要的。

另一种方法是创build普通图像的补丁9图像 ,并按照您希望的方式进行缩放。

你可以通过在angular落放9个补丁点来显示内容的中心位置,这样可以明显地保持你的比例(假设图像的最外边是可重复/透明的)。

希望你明白了。

使用a.ch描述的方法对我来说工作得非常好,除了我使用了这个比例更好的types,

 android:scaleType="centerCrop" 

以下是可用缩放types的完整列表: http : //developer.android.com/reference/android/widget/ImageView.ScaleType.html

尝试使用InsetDrawable(为我工作得很好)。

只要给你这个可绘制的,并从四边中的任何一边你想要的插入(或填充)。

 InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom); 

它是专门用于设置背景绘制,尺寸较小或比视图。

看到这里: https : //developer.android.com/reference/android/graphics/drawable/InsetDrawable.html

老问题,但没有其他答案为我工作。 但是,这个XML代码做到了:

 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:scaleType="centerCrop" android:src="@drawable/background_image"/> </RelativeLayout> 

如果您的位图宽度比较大,请使用android:gravity="fill_vertical" 。 否则,使用android:gravity="fill_horitzonal" 。 这与在ImageView上使用android:scaleType="centerCrop"具有类似的效果。

 <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill_vertical" android:src="@drawable/image" /> 

如果您支持多个方向,则可以在drawable-port文件夹中创build一个位图XML文件,而在drawable-land文件夹中创build另一个位图XML文件。

我想在我的自定义Drawable类中做类似的事情。 以下是重要的部分:

 public class CustomBackgroundDrawable extends Drawable { private Rect mTempRect = new Rect(); private Paint mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); ... public void draw(@NonNull Canvas canvas) { Rect bounds = getBounds(); if (mBitmap != null ) { if (mScaleType == ScaleType.SCALE_FILL) { //bitmap scales to fill the whole bounds area (bitmap can be cropped) if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min(mBitmap.getWidth()/(float)bounds.width(), mBitmap.getHeight()/(float)bounds.height()); float bitmapVisibleWidth = scale * bounds.width(); float bitmapVisibleHeight = scale * bounds.height(); mTempRect.set((int)(mBitmap.getWidth()-bitmapVisibleWidth)/2, 0, (int)(bitmapVisibleWidth+mBitmap.getWidth())/2, (int)bitmapVisibleHeight); canvas.drawBitmap(mBitmap, mTempRect, bounds, mBitmapPaint); } } else if (mScaleType == ScaleType.SCALE_FIT) { //bitmap scales to fit in bounds area if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min((float)bounds.width()/mBitmap.getWidth(), (float)bounds.height()/mBitmap.getHeight()); float bitmapScaledWidth = scale * mBitmap.getWidth(); float bitmapScaledHeight = scale * mBitmap.getHeight(); int centerPadding = (int)(bounds.width()-bitmapScaledWidth)/2; mTempRect.set(bounds.left + centerPadding, bounds.top, bounds.right - centerPadding, bounds.top+(int)bitmapScaledHeight); canvas.drawBitmap(mBitmap, null, mTempRect, mBitmapPaint); } } } } 

使用这种方法,您可以灵活地应用所需的任何比例逻辑