Android的 - 保持纵横比对背景图像上的默认按钮(Android - Keep aspect

2019-10-17 09:05发布

有没有什么办法保持绘制的宽高比时作为背景上的应用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()方法。

Answer 1:

我最近面临同样的问题,用于设置的背景图像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 ,请执行以下操作:

  1. 声明你的Activity作为实现者View.OnLayoutChangeListener接口:

     public class MyActivity extends Activity implements View.OnLayoutChangeListener { ... } 
  2. 注册您的Activity作为监听器布局的变化View

     @Override public void onCreate(Bundle savedInstanceState) { ... myView = (View) findViewById(R.id.myView); myView.addOnLayoutChangeListener(this); ... } 
  3. 检测为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; } } 


文章来源: Android - Keep aspect ratio on background image on default Button