有没有什么办法保持绘制的宽高比时作为背景上的应用Button
(不能使用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()
方法。
我最近面临同样的问题,用于设置的背景图像ImageView
。 该解决方案,我想出了与任何工程View
,所以它应该涵盖Button
为好。
问题是, View
总是绵延其背景的充分程度View
的宽度和高度,不管是作为背景提供的绘制对象的缩放。 正如你对未能提供专门的可绘制表明,这不能将其设置为背景,因为之前的图像缩放的任何手段来抵消报告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
的变化,由于布局处理。 要做到这一点,假设(一)您的View
被确定myView
在你的布局XML,以及(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; } }