如果我们不设置LinearLayout的宽度或高度,即设置wrap_content时,此时设置背景时,LinearLayout的宽度和高度会和背景图的宽高一致。这种情况有时是我们不想要看到的。如图:
而我实际想要的效果是:
这种情况对于现有的api是无解的。如何解决那,变换方式,我们可以对LinearLayout进行改进。
package com.example.test; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.util.AttributeSet; import android.widget.LinearLayout; public class BgLinearLayout extends LinearLayout{ public BgLinearLayout(Context context) { super(context); this.setWillNotDraw(false);//设置需要重写onDraw(),否则onDraw()不会执行 } public BgLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); this.setWillNotDraw(false); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.header_bg); bitmap = resizeBitmap_width(bitmap, this.getWidth());//按宽度比缩放图片 canvas.drawBitmap(bitmap, 0, 0, null); } /** * 缩放图片 * @param bitmap * @param w * @return */ public static Bitmap resizeBitmap_width(Bitmap bitmap, int w) { if (bitmap != null) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); float scaleSize = ((float) w) / width; Matrix matrix = new Matrix(); matrix.postScale(scaleSize, scaleSize); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); return resizedBitmap; } else { return null; } } }
已重写LinearLayout为例,其实其他任何容器控件都可以。首先获得背景图的Bitmap,然后将其按LinearLayout得宽度进行缩放,使其与LinearLayout的宽度一致,最后调用canvas.drawBitmap将bitmap滑到画布上。结果就是上图的图2。
原理:由于是onDraw(Canvas canvas)将背景画上去的,而此时LinearLayout的宽高早已确定,canvas画布的大小也就确定了,图片在大也不会撑开。