缩放图像保持其纵横比在背景中可绘制

til*_*lex 58 scaling android android-drawable android-background android-bitmap

如何使背景图像适合视图,但在<bitmap />用作背景可绘制XML 时保持其纵横比?没有<bitmap>android:gravity值给出预期效果的.

a.c*_*ch. 60

仅在xml文件中实现操作background属性是不可能的.有两种选择:

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

  2. 您使用ImageView而不是背景将其放置为第一个布局的元素并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>
    
    Run Code Online (Sandbox Code Playgroud)

  • ScaleType的`centerCrop`选项对此非常有用. (6认同)
  • 所有可能的`android:scaleType`值都没有给出所需的效果.只有在我根本没有指定`scaleType`时,图像才能保持其宽高比. (3认同)

Ion*_*gru 34

有一种简单的方法可以从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>
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是,如果没有足够的空间,你的图像将无法完全显示,但它将被剪裁,我找不到直接从drawable做到这一点的方法.但是从我做过的测试来看,它的效果非常好,而且它并没有削减那么多的图像.您可以使用重力选项进行更多操作.

另一种方法是创建一个布局,你将使用a ImageView并设置scaleTypeto fitCenter.

希望这些信息可以帮助您实现您想要的目标.

  • **这并不能回答问题。** (3认同)

Kam*_*rev 5

我想在我的自定义 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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