如果我们不设置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画布的大小也就确定了,图片在大也不会撑开。