下面列出了android.widget.ImageView#getImageMatrix ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Rect getDrawableBoundsInView(ImageView iv) {
if (iv != null && iv.getDrawable() != null) {
Drawable d = iv.getDrawable();
Rect result = new Rect();
iv.getGlobalVisibleRect(result);
Rect tDrawableRect = d.getBounds();
Matrix drawableMatrix = iv.getImageMatrix();
float[] values = new float[9];
if (drawableMatrix != null) {
drawableMatrix.getValues(values);
}
result.left += (int) values[2];
result.top += (int) values[5];
result.right = (int) ((float) result.left + (float) tDrawableRect.width() * (values[0] == 0.0F ? 1.0F : values[0]));
result.bottom = (int) ((float) result.top + (float) tDrawableRect.height() * (values[4] == 0.0F ? 1.0F : values[4]));
return result;
} else {
return null;
}
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ImageMatrixCorrector corrector = getCorrector();
ImageView imageView = corrector.getImageView();
Matrix matrix = imageView.getImageMatrix();
float[] values = getValues();
matrix.getValues(values);
float dx = (float) animation.getAnimatedValue(PROPERTY_TRANSLATE_X);
dx = corrector.correctAbsolute(Matrix.MTRANS_X, dx) - values[Matrix.MTRANS_X];
float dy = (float) animation.getAnimatedValue(PROPERTY_TRANSLATE_Y);
dy = corrector.correctAbsolute(Matrix.MTRANS_Y, dy) - values[Matrix.MTRANS_Y];
matrix.postTranslate(dx, dy);
imageView.invalidate();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ImageMatrixCorrector corrector = getCorrector();
ImageView imageView = corrector.getImageView();
if(imageView.getDrawable() != null) {
Matrix matrix = imageView.getImageMatrix();
float[] values = getValues();
matrix.getValues(values);
float sx = (float) animation.getAnimatedValue();
sx = corrector.correctAbsolute(Matrix.MSCALE_X, sx) / values[Matrix.MSCALE_X];
if (translate) {
matrix.postScale(sx, sx, px, py);
} else {
matrix.postScale(sx, sx);
}
corrector.performAbsoluteCorrections();
imageView.invalidate();
}
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if(v instanceof ImageView) {
ImageView iv = (ImageView) v;
Drawable drawable = iv.getDrawable();
if(drawable != null) {
float vw = iv.getWidth();
float vh = iv.getHeight();
float dw = drawable.getIntrinsicWidth();
float dh = drawable.getIntrinsicHeight();
Matrix matrix = iv.getImageMatrix();
matrix.getValues(VALUES);
float tx = VALUES[Matrix.MTRANS_X] + dx;
float sdw = dw * VALUES[Matrix.MSCALE_X];
//Log.d(TAG, "sdw: " + sdw + " vw: " + vw);
return VALUES[Matrix.MSCALE_X] / centerInsideScale(vw, vh, dw, dh) > scaleThreshold && !translationExceedsBoundary(tx, vw, sdw) && sdw > vw && pointerCount == 1; // Assumes x-y scales are equal
}
}
return super.canScroll(v, checkV, dx, x, y);
}
/**
*
* @param imageView
* @param width
* @param height
*/
public static final void updateImageViewMatrix(ImageView imageView, float width, float height) {
Drawable drawable = imageView.getDrawable();
if(drawable == null) {
throw new NullPointerException("ImageView drawable is null");
}
Matrix matrix = imageView.getImageMatrix();
if(!matrix.isIdentity()) {
float[] values = new float[9];
matrix.getValues(values);
RectF src = new RectF();
src.left = 0;
src.top = 0;
src.right = width;
src.bottom = height;
RectF dst = new RectF();
dst.left = values[Matrix.MTRANS_X];
dst.top = values[Matrix.MTRANS_Y];
dst.right = dst.left + (drawable.getIntrinsicWidth() * values[Matrix.MSCALE_X]);
dst.bottom = dst.top + (drawable.getIntrinsicHeight() * values[Matrix.MSCALE_Y]);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
}
}
public static Info getImageViewInfo(ImageView imgView) {
int[] p = new int[2];
getLocation(imgView, p);
Drawable drawable = imgView.getDrawable();
Matrix matrix = imgView.getImageMatrix();
int width = getDrawableWidth(drawable);
int height = getDrawableHeight(drawable);
RectF imgRect = new RectF(0, 0, width, height);
matrix.mapRect(imgRect);
RectF rect = new RectF(p[0] + imgRect.left, p[1] + imgRect.top, p[0] + imgRect.right, p[1] + imgRect.bottom);
RectF widgetRect = new RectF(0, 0, imgView.getWidth(), imgView.getHeight());
RectF baseRect = new RectF(widgetRect);
PointF screenCenter = new PointF(widgetRect.width() / 2, widgetRect.height() / 2);
return new Info(rect, imgRect, widgetRect, baseRect, screenCenter, 1, 0, imgView.getScaleType());
}
public CropHighlightView(ImageView ctx, Rect imageRect, RectF cropRect) {
mContext = ctx;
final int progressColor = mContext.getResources().getColor(R.color.box_border);
mCropCornerHandleRadius = mContext.getResources().getDimensionPixelSize(R.dimen.crop_handle_corner_radius);
mCropEdgeHandleRadius = mContext.getResources().getDimensionPixelSize(R.dimen.crop_handle_edge_radius);
mHysteresis = mContext.getResources().getDimensionPixelSize(R.dimen.crop_hit_hysteresis);
final int edgeWidth = mContext.getResources().getDimensionPixelSize(R.dimen.crop_edge_width);
mMatrix = new Matrix(ctx.getImageMatrix());
Log.i(LOG_TAG, "image = " + imageRect.toString() + " crop = " + cropRect.toString());
mTrapezoid = new CroppingTrapezoid(cropRect, imageRect);
mDrawRect = computeLayout();
mFocusPaint.setARGB(125, 50, 50, 50);
mFocusPaint.setStyle(Paint.Style.FILL);
mOutlinePaint.setARGB(0xFF, Color.red(progressColor), Color.green(progressColor), Color.blue(progressColor));
mOutlinePaint.setStrokeWidth(edgeWidth);
mOutlinePaint.setStyle(Paint.Style.FILL_AND_STROKE);
mOutlinePaint.setAntiAlias(true);
}
private static Matrix copyImageMatrix(ImageView view) {
switch (view.getScaleType()) {
case FIT_XY:
return fitXYMatrix(view);
case CENTER_CROP:
return centerCropMatrix(view);
default:
return new Matrix(view.getImageMatrix());
}
}
private static SharedElementOriginalState getOldSharedElementState(View view, String name,
Bundle transitionArgs) {
SharedElementOriginalState state = new SharedElementOriginalState();
state.mLeft = view.getLeft();
state.mTop = view.getTop();
state.mRight = view.getRight();
state.mBottom = view.getBottom();
state.mMeasuredWidth = view.getMeasuredWidth();
state.mMeasuredHeight = view.getMeasuredHeight();
state.mTranslationZ = view.getTranslationZ();
state.mElevation = view.getElevation();
if (!(view instanceof ImageView)) {
return state;
}
Bundle bundle = transitionArgs.getBundle(name);
if (bundle == null) {
return state;
}
int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1);
if (scaleTypeInt < 0) {
return state;
}
ImageView imageView = (ImageView) view;
state.mScaleType = imageView.getScaleType();
if (state.mScaleType == ImageView.ScaleType.MATRIX) {
state.mMatrix = new Matrix(imageView.getImageMatrix());
}
return state;
}
@Override
public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix,
RectF screenBounds) {
// This is a replacement for the platform's overzealous onCaptureSharedElementSnapshot.
// If you look at what it's doing, it's creating an ARGB_8888 copy of every single shared
// element.
// This was causing us to allocate 7+mb of bitmaps on every P3 load even though we didn't
// need any of them...
// They're slow to garbage collect and lead to OOMs too....
// This just pulls the bitmap from the ImageView that we're already using and shoves it into
// the a bundle formatted all nice
// and pretty like the platform wants it to be and never has to know the difference.
if (sharedElement instanceof ImageView) {
ImageView imageView = (ImageView) sharedElement;
Drawable drawable = ((ImageView) sharedElement).getDrawable();
if (drawable != null && drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bundle bundle = new Bundle();
bundle.putParcelable(BUNDLE_SNAPSHOT_BITMAP, bitmap);
bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE, imageView.getScaleType().toString());
if (imageView.getScaleType() == ImageView.ScaleType.MATRIX) {
Matrix matrix = imageView.getImageMatrix();
float[] values = new float[9];
matrix.getValues(values);
bundle.putFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX, values);
}
return bundle;
}
}
return null;
}
/**
* 返回的 宽高数组 是图片 在当前分辨率手机的宽高
*
* @param imageView
* @return
*/
public static float[] measureDrawableWH(final ImageView imageView) {
Drawable drawable = imageView.getDrawable();
Matrix mar = imageView.getImageMatrix();
int intrinsicHeight = drawable.getIntrinsicHeight();
int intrinsicWidth = drawable.getIntrinsicWidth();
return new float[]{intrinsicWidth, intrinsicHeight};
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder viewHolder;
if (convertView == null) {
// this is call when new view
convertView = LayoutInflater.from(this.context).inflate(R.layout.item, null, false);
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
TextView textView = (TextView) convertView.findViewById(R.id.text);
imageView.setScaleType(ImageView.ScaleType.MATRIX);
// hardcode the background image
if (position % 2 == 0) {
imageView.setImageResource(R.drawable.lorempixel2);
} else if (position % 3 == 0) {
imageView.setImageResource(R.drawable.lorempixel3);
} else {
imageView.setImageResource(R.drawable.lorempixel);
}
// since the image size is set to 400 x 300 we will hardcode the initial translation to the center for new item
Matrix matrix = imageView.getImageMatrix();
matrix.postTranslate(0, -100);
imageView.setImageMatrix(matrix);
// use the viewholder
viewHolder = new ViewHolder();
viewHolder.imageView = imageView;
viewHolder.textView = textView;
convertView.setTag(viewHolder);
}
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.textView.setText("Row "+ position);
return convertView;
}
@Override
public Matrix get(ImageView object) {
return object.getImageMatrix();
}
@Override
public Matrix get(ImageView object) {
return object.getImageMatrix();
}
@Override
public void draw(Canvas canvas) {
final ImageView parentView = mParentView.get();
if (parentView == null) {
return;
}
final int parentViewWidth = parentView.getWidth();
final int parentViewHeight = parentView.getHeight();
mMatrix = parentView.getImageMatrix();
mMatrix.getValues(mMatrixValues);
final float translationX = mMatrixValues[Matrix.MTRANS_X];
final float translationY = mMatrixValues[Matrix.MTRANS_Y];
final float scale = mMatrixValues[Matrix.MSCALE_X];
// If the matrix values have changed, the decode queue must be cleared in order to avoid decoding unused tiles
if (translationX != mLastMatrixValues[Matrix.MTRANS_X] || translationY != mLastMatrixValues[Matrix.MTRANS_Y] || scale != mLastMatrixValues[Matrix.MSCALE_X]) {
mDecodeQueue.clear();
}
mLastMatrixValues = Arrays.copyOf(mMatrixValues, mMatrixValues.length);
// The scale required to display the whole Bitmap inside the ImageView. It will be the minimum allowed scale value
final float minScale = Math.min(parentViewWidth / (float) mIntrinsicWidth, parentViewHeight / (float) mIntrinsicHeight);
// The number of allowed levels for this Bitmap. Each subsequent level is half size of the previous one
final int levelCount = Math.max(1, MathUtils.ceilLog2(mIntrinsicWidth / (mIntrinsicWidth * minScale)));
// sampleSize = 2 ^ currentLevel
final int currentLevel = MathUtils.clamp(MathUtils.floorLog2(1 / scale), 0, levelCount - 1);
final int sampleSize = 1 << currentLevel;
final int currentTileSize = mTileSize * sampleSize;
final int horizontalTiles = (int) Math.ceil(mIntrinsicWidth / (float) currentTileSize);
final int verticalTiles = (int) Math.ceil(mIntrinsicHeight / (float) currentTileSize);
final int visibleAreaLeft = Math.max(0, (int) (-translationX / scale));
final int visibleAreaTop = Math.max(0, (int) (-translationY / scale));
final int visibleAreaRight = Math.min(mIntrinsicWidth, Math.round((-translationX + parentViewWidth) / scale));
final int visibleAreaBottom = Math.min(mIntrinsicHeight, Math.round((-translationY + parentViewHeight) / scale));
mVisibleAreaRect.set(visibleAreaLeft, visibleAreaTop, visibleAreaRight, visibleAreaBottom);
boolean cacheMiss = false;
for (int i = 0; i < horizontalTiles; i++) {
for (int j = 0; j < verticalTiles; j++) {
final int tileLeft = i * currentTileSize;
final int tileTop = j * currentTileSize;
final int tileRight = (i + 1) * currentTileSize <= mIntrinsicWidth ? (i + 1) * currentTileSize : mIntrinsicWidth;
final int tileBottom = (j + 1) * currentTileSize <= mIntrinsicHeight ? (j + 1) * currentTileSize : mIntrinsicHeight;
mTileRect.set(tileLeft, tileTop, tileRight, tileBottom);
if (Rect.intersects(mVisibleAreaRect, mTileRect)) {
final Tile tile = new Tile(mInstanceId, mTileRect, i, j, currentLevel);
Bitmap cached = null;
synchronized (sBitmapCacheLock) {
cached = sBitmapCache.get(tile.getKey());
}
if (cached != null) {
canvas.drawBitmap(cached, null, mTileRect, mPaint);
} else {
cacheMiss = true;
synchronized (mDecodeQueue) {
if (!mDecodeQueue.contains(tile)) {
mDecodeQueue.add(tile);
}
}
// The screenNail is used while the proper tile is being decoded
final int screenNailLeft = Math.round(tileLeft * mScreenNail.getWidth() / (float) mIntrinsicWidth);
final int screenNailTop = Math.round(tileTop * mScreenNail.getHeight() / (float) mIntrinsicHeight);
final int screenNailRight = Math.round(tileRight * mScreenNail.getWidth() / (float) mIntrinsicWidth);
final int screenNailBottom = Math.round(tileBottom * mScreenNail.getHeight() / (float) mIntrinsicHeight);
mScreenNailRect.set(screenNailLeft, screenNailTop, screenNailRight, screenNailBottom);
canvas.drawBitmap(mScreenNail, mScreenNailRect, mTileRect, mPaint);
}
}
}
}
// If we had a cache miss, we will need to redraw until all needed tiles have been decoded by our worker thread
if (cacheMiss) {
invalidateSelf();
}
}