我有ImageView
,全宽和宽:高= 3:1,我们称之为1200 x 400.我想在Drawable
中显示两个ImageView
,这两者都只在运行时知道。其中一个drawables应根据“center-crop”放入ImageView
(假设drawable有宽度:height> 3,这意味着宽度适合并且顶部和底部裁剪),另一个应该按照自定义因素进行居中和缩放。
我有一些代码可以做到这一点,但对我来说似乎不必要的复杂;当我从Bitmap
创建新的LayerDrawable
,然后从BitmapDrawable
创建BitmapDrawable
时,我才能按需要工作,并在LayerDrawable
上再次设置所需的边界虽然我已经在LayerDrawable
设置了边界 - 但是如果我不执行额外的步骤,那些边界就会被忽略。我更倾向于生成.setImageDrawable()
,以便我可以在LayerDrawable
中使用它,但我不知道如何使用它。如果我尝试Android会做什么对我没有任何意义。我做错了什么?
这就是我double divide(int k, int n) {
return ((double)k)/n;
}
int verticalPaddingForHorizontalFit(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight){
// you want to draw a drawable into a view, with an exact match in the width. Then either [1] or [2]
// [1] the view is taller than the drawable (i.e., height/width bigger for the view)
// --> method result is positive,
// and gives the amount of padding top and bottom
// [2] the drawable is taller
// --> method result is negative,
// and gives (minus) the amount that needs to be clipped from top and bottom
// such that the drawable is vertically centered
double viewAspect = divide(viewHeight, viewWidth );
double drawableAspect = divide(drawableHeight, drawableWidth);
return (int)Math.round(0.5 * viewWidth * (viewAspect - drawableAspect));
}
int[] paddingWhenCenteredAt(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight, double drawableScale, int centerX, int centerY){
// scale the drawable with drawableScale, and put it into the view
// such that the center of the drawable has coordinates (centerX, centerY)
// return the padding needed as array of left, top, right, bottom, in that order
// negative values indicating clipping instead of padding
double w = drawableScale * drawableWidth;
double h = drawableScale * drawableHeight;
double left = centerX - 0.5*w;
double right = viewWidth - (centerX + 0.5*w);
double top = centerY - 0.5*h;
double bottom = viewHeight - (centerY + 0.5*h);
return new int[]{(int)Math.round(left), (int)Math.round(top), (int)Math.round(right), (int)Math.round(bottom)};
}
LayerDrawable makeLayerDrawable(Resources r, int outputWidth, int outputHeight, Bitmap bm1, Bitmap bm2){
Drawable[] layers = new Drawable[2];
BitmapDrawable bmd1 = new BitmapDrawable(r, bm1);
int width1 = bmd1.getIntrinsicWidth();
int height1 = bmd1.getIntrinsicHeight();
layers[0] = bmd1;
BitmapDrawable bmd2 = new BitmapDrawable(r, bm2);
int width2 = bmd2.getIntrinsicWidth();
int height2 = bmd2.getIntrinsicHeight();
layers[1] = bmd2;
LayerDrawable result = new LayerDrawable(layers);
int vPad = verticalPaddingForHorizontalFit(outputWidth, outputHeight, width1, height1);
result.setLayerInset(0, 0, vPad, 0, vPad);
int[] ltrb = paddingWhenCenteredAt(outputWidth, outputHeight, width2, height2, 0.5, outputWidth/2, outputHeight/2);
result.setLayerInset(1, ltrb[0], ltrb[1], ltrb[2], ltrb[3]);
result.setBounds(0, 0, outputWidth, outputHeight);
return result;
}
LayerDrawable
(我测试了Bitmap bm1 2400 x 1200像素和Bitmap bm2 800 x 300像素。)
现在,如果我只使用那个 myImageView.setImageDrawable(layd);
,就像这样
ImageView
LayoutParameters
将没有所需的大小(高度更改。)如果我再次使用 LayerDrawable layd = makeLayerDrawable(r, outputWidth, outputHeight, bm1, bm2);
Bitmap b = Bitmap.createBitmap(outputWidth, outputHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
layd.draw(canvas);
BitmapDrawable result = new BitmapDrawable(getResources(), b);
result.setBounds(0, 0, outputWidth, outputHeight);
myImageView.setImageDrawable(result);
设置布局,我可以阻止它,但是,然后,drawables没有正确显示。相反,我这样做
{{1}}
它有效。
Here是github上的完整代码
答案 0 :(得分:0)
我会考虑编写你自己的Drawable
类,这看起来并不那么难。只需从Drawable
扩展并覆盖draw()
,您可以执行与剪切代码中相同的计算,只需绘制到具有所需宽高比的分层(堆叠)位图。 Canvas.drawBitmap()似乎适用于您的问题。