【问题标题】:Scale image keeping its aspect ratio in background drawable缩放图像在背景可绘制中保持其纵横比
【发布时间】:2012-03-27 13:59:34
【问题描述】:

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

【问题讨论】:

  • 你试过ScaleType吗?
  • 试试 android:scaleType="matrix"
  • ScaleType 用于 ImageView。位图不支持。

标签: android scaling android-drawable android-bitmap android-background


【解决方案1】:

仅在 xml 文件中操作背景属性是不可能的。有两种选择:

  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>
    

【讨论】:

  • 所有可能的android:scaleType 值都不会产生所需的效果。仅当我根本不指定 scaleType 时,图像才适合视图保持其纵横比。
【解决方案2】:

有一种简单的方法可以从可绘制对象中做到这一点:

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>

唯一的缺点是如果没有足够的空间,您的图像将无法完全显示,但会被剪裁,我找不到直接从可绘制对象中执行此操作的方法。但从我所做的测试来看,它工作得很好,而且它并没有剪掉那么多的图像。您可以更多地使用重力选项。

另一种方法是创建一个布局,您将在其中使用 ImageView 并将 scaleType 设置为 fitCenter强>。

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

【讨论】:

  • 这样可以保持图像不缩放且很小,并且只显示在底部。
  • 确实,如果需要扩展,其他解决方案更合适。如您所见,这些属性不涉及任何类型的缩放。
  • 这不能回答问题。
【解决方案3】:

我想在我的自定义 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);
            }
        }
    }
}

通过这种方法,您可以灵活地应用所需的任何缩放逻辑

【讨论】:

    【解决方案4】:

    另一种方法是为您的常规图像创建patch 9 images,并让它按照您想要的方式进行缩放。

    您可以通过在角落放置 9 个补丁点来使其内容居中,这将明显保持您的比例(假设图像的最外边缘是可重复/透明的)。

    希望你能明白。

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

      • 很遗憾,它不适用于android:background
      【解决方案6】:

      使用 a.ch 描述的方法对我来说效果很好,除了我使用的这种比例类型对我需要的效果更好:

      android:scaleType="centerCrop"
      

      以下是可用秤类型的完整列表: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

      【讨论】:

      【解决方案7】:

      尝试使用 InsetDrawable(对我来说效果很好)。

      只需从四个侧面中的任何一个给它您的可绘制对象和插入(或填充)即可。

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

      专门用于设置背景drawable,大小小于或小于View。

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

      【讨论】:

        【解决方案8】:

        老问题,但没有其他答案对我有用。然而,这个 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>
        

        【讨论】:

          【解决方案9】:

          为了适合图像到可用空间(或者如果您在 dp 中设置了 widthheight),我尝试过以下方法,如果图像不太宽。

          在这里,我为 方形图像 设置了相同的 widthheight [或者您可以在两者上都使用wrap_content]。

          <RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent" >
          
              <ImageView
                  android:layout_width="80dp"
                  android:layout_height="80dp"
                  android:layout_alignParentTop="true"
                  android:adjustViewBounds="true"
                  android:scaleType="fitCenter"
                  android:src="@drawable/background_image"/> 
          
          </RelativeLayout>
          

          adjust view boundsscale type center fit 可以解决问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-11-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-22
            • 2017-05-24
            • 2012-08-11
            相关资源
            最近更新 更多