有什么方法可以在Button
上作为背景应用时保持drawable的宽高比(不能使用ImageButton
(需要Button
上的文字),不能使用setCompoundDrawables()
,因为这也不符合我的要求(我自己的班级支持添加背景,同时仍保留原始的Android默认按钮,另外我需要在按钮中间设置te背景,而不是留下,右,上或下))。
我尝试使用ScaleDrawable
的解决方案,但要么我做错了要么行不通:
Bitmap scaled = Bitmap.createScaledBitmap(original, (int)newBmpWidth, (int)newBmpHeight, false);
BitmapDrawable bd = new BitmapDrawable(scaled);
ScaleDrawable sd = new ScaleDrawable(bd, Gravity.CENTER, a, b);
//for a and b I tried lots of different values, ranging from 0.07f to 1000
sd.setLevel(1);
然后我使用ScaleDrawable
作为背景,但无论如何它都会被拉伸。
我也尝试了InsetDrawable
,但是,无论是我做错了什么还是行不通,期待第一次:
BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);
InsetDrawable mInsetDrawable = new InsetDrawable(mBitmapDrawable, mLeftOffset, 0, mRightOffset, 0);
然后我使用InsetDrawable
作为背景,但无论如何这也会被拉伸。
有没有办法应用背景但保持宽高比Button
?我可以找到ImageButtons
的大量答案,但遗憾的是Button
没有setImageBitmap()
或setScaleType()
方法。
答案 0 :(得分:1)
我最近遇到了设置ImageView
背景图片的同样问题。我提出的解决方案适用于任何View
,因此它也应涵盖Button
。
问题在于View
始终将其背景延伸到View
的宽度和高度的全部范围,无论Drawable作为背景提供的缩放比例。由于您未能提供专门的Drawables的报告表明,在将图像设置为背景之前,无法通过任何缩放图像来抵消这种情况,因为View
只会采用图像尺寸,无论它们是什么,并且可以独立地再次缩放图像尺寸填补View
区域。
我的解决方案采用了不同的方法,因为如果我们能够提供与View
相同的宽高比的背景图像,那么就不会有失真。
下面的函数scaleKeepingAspect()
获取图像资源并回答包含缩放到所需宽度和高度的原始图像的BitmapDrawable
。以保持原始图像的纵横比的方式执行缩放,并且用透明像素填充适合所需框的最终剩余空间。原始图像以结果图像为中心。
private BitmapDrawable scaleKeepingAspect(Resources res, int id, int dstWidth, int dstHeight) {
Bitmap b = (new BitmapFactory()).decodeResource(res, id);
float scaleX = (float) dstWidth / b.getWidth();
float scaleY = (float) dstHeight / b.getHeight();
float scale = scaleX < scaleY ? scaleX : scaleY;
int sclWidth = Math.round(scale * b.getWidth());
int sclHeight = Math.round(scale * b.getHeight());
b = Bitmap.createScaledBitmap(b, sclWidth, sclHeight, false);
int[] pixels = new int[sclWidth * sclHeight];
b.getPixels(pixels, 0, sclWidth, 0, 0, sclWidth, sclHeight);
b = Bitmap.createBitmap(dstWidth, dstHeight, b.getConfig());
b.setPixels(pixels, 0, sclWidth, (dstWidth - sclWidth) / 2, (dstHeight - sclHeight) / 2, sclWidth, sclHeight);
return new BitmapDrawable(res, Bitmap.createBitmap(b));
}
在布局更改事件期间,设置scaleKeepingAspect()
背景时使用View
的正确位置,以便在View
的边界更改到期时正确更新背景布局处理。为此,假设(a)您的View
在您的布局xml中由myView
标识,并且(b)您的背景图片是文件res/drawable/background.png
,请执行以下操作:
声明您的Activity
是View.OnLayoutChangeListener
接口的实现者:
public class MyActivity extends Activity implements View.OnLayoutChangeListener {
...
}
注册Activity
作为您View
的布局更改的聆听者:
@Override public void onCreate(Bundle savedInstanceState) {
...
myView = (View) findViewById(R.id.myView);
myView.addOnLayoutChangeListener(this);
...
}
检测布局更改处理程序中的View
布局更新,并在需要时更新其背景:
@Override public void onLayoutChange (View v,
int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (left == right || top == bottom || (
left == oldLeft && top == oldTop &&
right == oldRight && bottom == oldBottom))
return;
switch (v.getId()) {
case R.id.myView:
v.setBackground(
scaleKeepingAspect(
getResources(),
R.drawable.background,
v.getWidth(),
v.getHeight()));
break;
}
}