我有一个ImageView,它显示的png的纵横比比设备的要大(垂直地说-意味着它更长)。我想要在保持纵横比的同时显示,匹配父对象的宽度,并将图像视图固定在屏幕顶部。
我使用CENTER_CROP作为缩放类型的问题是,它会(可以理解)将缩放的图像居中,而不是将顶部边缘与图像视图的顶部边缘对齐。
FIT_START的问题是图像将适合屏幕高度,而不是填充宽度。
我已经解决了这个问题,我使用一个自定义的ImageView,覆盖onDraw(Canvas),并使用画布手动处理这个问题;这种方法的问题是: 1)我担心可能有更简单的解决方案,2)当尝试在构造函数中调用super(AttributeSet)时,当尝试设置330kb的src img时,当堆有3mb的空闲空间(堆大小为6mb)时,我得到了VM mem异常,但找不出原因。
非常欢迎任何想法/建议/解决方案:)
谢谢
附注:我认为一个解决方案可能是使用矩阵缩放类型并自己做,但这似乎与我目前的解决方案相同或更多的工作!
发布于 2011-06-14 00:47:14
好的,我有一个可行的解决方案。Darko的提示让我再次查看了ImageView类(谢谢),并使用矩阵应用了转换(正如我最初怀疑的那样,但在第一次尝试中没有成功!)。在我的自定义imageView类中,我在构造函数中的super()之后调用setScaleType(ScaleType.MATRIX),并具有以下方法。
@Override
protected boolean setFrame(int l, int t, int r, int b)
{
Matrix matrix = getImageMatrix();
float scaleFactor = getWidth()/(float)getDrawable().getIntrinsicWidth();
matrix.setScale(scaleFactor, scaleFactor, 0, 0);
setImageMatrix(matrix);
return super.setFrame(l, t, r, b);
}我将int放在setFrame()方法中,就像在ImageView中一样,对configureBounds()的调用在这个方法中,这是所有缩放和矩阵工作发生的地方,所以对我来说似乎是合乎逻辑的(如果你不同意的话)。
下面是来自安卓开源项目的super.setFrame()方法
@Override
protected boolean setFrame(int l, int t, int r, int b) {
boolean changed = super.setFrame(l, t, r, b);
mHaveFrame = true;
configureBounds();
return changed;
}查找完整的类src here
发布于 2012-07-23 03:17:15
下面是我在底部居中显示的代码。
顺便说一句,Dori的代码中有一个小错误:因为super.frame()是在最后调用的,所以getWidth()方法可能会返回错误的值。
如果您想将它放在顶部居中,只需删除postTranslate行,就完成了。
好的是,使用此代码,您可以将其移动到您想要的任何位置。(对,中锋=>没问题;)
public class CenterBottomImageView extends ImageView {
public CenterBottomImageView(Context context) {
super(context);
setup();
}
public CenterBottomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public CenterBottomImageView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
setup();
}
private void setup() {
setScaleType(ScaleType.MATRIX);
}
@Override
protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {
if (getDrawable() == null) {
return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
}
float frameWidth = frameRight - frameLeft;
float frameHeight = frameBottom - frameTop;
float originalImageWidth = (float)getDrawable().getIntrinsicWidth();
float originalImageHeight = (float)getDrawable().getIntrinsicHeight();
float usedScaleFactor = 1;
if((frameWidth > originalImageWidth) || (frameHeight > originalImageHeight)) {
// If frame is bigger than image
// => Crop it, keep aspect ratio and position it at the bottom and center horizontally
float fitHorizontallyScaleFactor = frameWidth/originalImageWidth;
float fitVerticallyScaleFactor = frameHeight/originalImageHeight;
usedScaleFactor = Math.max(fitHorizontallyScaleFactor, fitVerticallyScaleFactor);
}
float newImageWidth = originalImageWidth * usedScaleFactor;
float newImageHeight = originalImageHeight * usedScaleFactor;
Matrix matrix = getImageMatrix();
matrix.setScale(usedScaleFactor, usedScaleFactor, 0, 0); // Replaces the old matrix completly
//comment matrix.postTranslate if you want crop from TOP
matrix.postTranslate((frameWidth - newImageWidth) /2, frameHeight - newImageHeight);
setImageMatrix(matrix);
return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
}
}初学者提示:如果它不能正常工作,你可能不得不使用extends androidx.appcompat.widget.AppCompatImageView而不是ImageView
发布于 2016-06-27 16:40:21
您无需编写自定义图像视图即可获取TOP_CROP功能。您只需要修改ImageView的matrix即可。
ImageView的scaleType设置为matrix:https://stackoverflow.com/questions/6330084
复制相似问题