以下是我的自定义图片视图-
CropImgImageView extends AppCompatImageView {
private Matrix imageMatrix;
private MatrixUtils matrixUtils;
private GestureProcessor gestureDetector;
private RectF allowedBounds;
private RectF imageBounds;
private RectF realImageBounds;
private OnImagePositionedListener imagePositionedListener;
private CropImgImageViewConfig config;
private boolean rotated = false;
public CropImgImageView(Context context, CropImgImageViewConfig config) {
super(context);
//setLayerType(View.LAYER_TYPE_HARDWARE, null);
initWith(config);
}
private void initWith(CropImgImageViewConfig c) {
config = c;
config.addConfigChangeListener(this);
imageBounds = new RectF();
allowedBounds = new RectF();
realImageBounds = new RectF();
matrixUtils = new MatrixUtils();
imageMatrix = new Matrix();
setScaleType(ScaleType.MATRIX);
gestureDetector = new GestureProcessor();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (hasImageSize()) {
placeImageToInitialPosition();
}
}
public void postRotate(float deltaAngle) {
if (deltaAngle != 0) {
updateImageBounds();
rotated = !rotated;
printScale(5);
float[] f = new float[9];
imageMatrix.getValues(f);
float scaleX = f[Matrix.MSCALE_X];
float scaleY = f[Matrix.MSCALE_Y];
imageMatrix.postRotate(deltaAngle, imageBounds.centerX(), imageBounds.centerY());
imageMatrix.postScale(scaleX, scaleY);
setImageMatrix(imageMatrix);
printScale(6);
Log.v("CropBound", "W "+getRealImageWidth()+ " H "+getRealImageHeight());
updateImageBounds();
Log.v("CropBound", "Bound W "+getImageWidth()+ " H "+getImageHeight());
//Log.v("CropBound", "View W "+getWidth()+ " H "+getHeight());
Log.v("CropBound", "Updated W "+getRealImageWidth()+ " H "+getRealImageHeight());
}
}
private void placeImageToInitialPosition() {
updateImageBounds();
moveImageToTheCenter();
if (config.getScale() == CropImgImageViewConfig.SCALE_UNSPECIFIED) {
switch (config.getImageInitialPosition()) {
case CENTER_CROP:
resizeImageToFillTheView();
break;
case CENTER_INSIDE:
resizeImageToBeInsideTheView();
break;
}
config.setScale(getCurrentScalePercent());
} else {
setScalePercent(config.getScale());
}
notifyImagePositioned();
}
private void resizeImageToFillTheView() {
float scale;
if (getWidth() < getHeight()) {
scale = ((float) getHeight()) / getImageHeight();
} else {
scale = ((float) getWidth()) / getImageWidth();
}
scaleImage(scale);
}
private void resizeImageToBeInsideTheView() {
float scale;
if (getImageWidth() < getImageHeight()) {
scale = ((float) getHeight()) / getImageHeight();
} else {
scale = ((float) getWidth()) / getImageWidth();
}
scaleImage(scale);
}
private void moveImageToTheCenter() {
updateImageBounds();
float deltaX = (getWidth() / 2f) - imageBounds.centerX();
float deltaY = (getHeight() / 2f) - imageBounds.centerY();
translateImage(deltaX, deltaY);
}
private float calculateMinScale() {
float viewWidth = getWidth(), viewHeight = getHeight();
if (getRealImageWidth() <= viewWidth && getRealImageHeight() <= viewHeight) {
return config.getMinScale();
}
float scaleFactor = viewWidth < viewHeight ?
viewWidth / getRealImageWidth() :
viewHeight / getRealImageHeight();
return scaleFactor * 0.8f;
}
private int getRealImageWidth() {
Drawable image = getDrawable();
return image != null ? image.getIntrinsicWidth() : -1;
}
private int getRealImageHeight() {
Drawable image = getDrawable();
return image != null ? image.getIntrinsicHeight() : -1;
}
public int getImageWidth() {
return (int) getImgBoundWidth(imageBounds);
}
public int getImageHeight() {
return (int) getImgBoundHeight(imageBounds);
}
public float getImgBoundWidth(RectF rectF){
if (rectF.left > rectF.right){
return rectF.left - rectF.right;
}else {
return rectF.right - rectF.left;
}
}
public float getImgBoundHeight(RectF rectF){
if (rectF.top > rectF.bottom){
return rectF.top - rectF.bottom;
}else {
return rectF.bottom - rectF.top;
}
}
public boolean hasImageSize() {
return getRealImageWidth() != -1 && getRealImageHeight() != -1;
}
public GestureProcessor getImageTransformGestureDetector() {
return gestureDetector;
}
@Override
public void onNewBounds(RectF bounds) {
updateImageBounds();
allowedBounds.set(bounds);
Log.v("CropBound", "Allowed B "+allowedBounds.left+" "+allowedBounds.right+ " "+allowedBounds.top+ " "+allowedBounds.bottom);
if (hasImageSize()) {
post(new Runnable() {
@Override
public void run() {
animateToAllowedBounds();
}
});
updateImageBounds();
invalidate();
}
}
private void animateToAllowedBounds() {
updateImageBounds();
printScale(1);
Matrix endMatrix = MatrixUtils.findTransformToAllowedBounds(
realImageBounds, imageMatrix,
allowedBounds);
MatrixAnimator animator = new MatrixAnimator();
animator.animate(imageMatrix, endMatrix, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
imageMatrix.set((Matrix) animation.getAnimatedValue());
printScale(2);
setImageMatrix(imageMatrix);
updateImageBounds();
invalidate();
}
});
}
private void setScalePercent(@FloatRange(from = 0.01f, to = 1f) float percent) {
percent = Math.min(Math.max(0.01f, percent), 1f);
float desiredScale = config.getMinScale() + config.getMaxScale() * percent;
float currentScale = matrixUtils.getScaleX(imageMatrix);
float factor = desiredScale / currentScale;
scaleImage(factor);
invalidate();
}
private void scaleImage(float factor) {
updateImageBounds();
scaleImage(factor, imageBounds.centerX(), imageBounds.centerY());
}
private void scaleImage(float factor, float pivotX, float pivotY) {
imageMatrix.postScale(factor, factor, pivotX, pivotY);
setImageMatrix(imageMatrix);
updateImageBounds();
}
private void translateImage(float deltaX, float deltaY) {
imageMatrix.postTranslate(deltaX, deltaY);
setImageMatrix(imageMatrix);
if (deltaX > 0.01f || deltaY > 0.01f) {
updateImageBounds();
}
}
private void updateImageBounds() {
printScale(3);
//if (rotated){
// realImageBounds.set(0, 0, getRealImageHeight(), getRealImageWidth());
//}else {
realImageBounds.set(0, 0, getRealImageWidth(), getRealImageHeight());
// }
imageBounds.set(realImageBounds);
imageMatrix.mapRect(imageBounds);
printScale(4);
}
private void printScale(int val){
float[] f = new float[9];
imageMatrix.getValues(f);
float scaleX = f[Matrix.MSCALE_X];
float scaleY = f[Matrix.MSCALE_Y];
Log.v("CropBound", "Bounds"+val+" Scale X "+scaleX+ " Y "+scaleY);
}
@Override
public void onConfigChanged() {
if (Math.abs(getCurrentScalePercent() - config.getScale()) > 0.001f) {
setScalePercent(config.getScale());
animateToAllowedBounds();
}
}
public void setImagePositionedListener(OnImagePositionedListener imagePositionedListener) {
this.imagePositionedListener = imagePositionedListener;
if (hasImageSize()) {
updateImageBounds();
notifyImagePositioned();
}
}
public RectF getImageRect() {
updateImageBounds();
return new RectF(imageBounds);
}
public void notifyImagePositioned() {
if (imagePositionedListener != null) {
RectF imageRect = new RectF(imageBounds);
CropImgUtils.constrainRectTo(0, 0, getWidth(), getHeight(), imageRect);
imagePositionedListener.onImagePositioned(imageRect);
}
}
private float getCurrentScalePercent() {
return CropImgUtils.boundValue(
0.01f + (matrixUtils.getScaleX(imageMatrix) - config.getMinScale()) / (config.getMaxScale()),
0.01f, 1f);
}
}
每次在imageMatrix.postRotate之后ic调用postRotate(90)时,我都会得到像imageMatrix这样的缩放比例
关于初始化-比例尺X 0.79999995 Y 0.79999995 第一次旋转-比例X 0.0 Y 0.0 第二旋转-比例尺X -0.79999995 Y -0.79999995 第三-比例尺X -0.0 Y -0.0 再次缩放X 0.79999995 Y 0.79999995
因此,当比例为0.0
时,图像视图会变黑
有解决方案吗?