下面列出了android.graphics.Matrix#setValues ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds.
*/
public Matrix fitScreen() {
mMinScaleX = 1f;
mMinScaleY = 1f;
Matrix save = new Matrix();
save.set(mMatrixTouch);
float[] vals = new float[9];
save.getValues(vals);
// reset all translations and scaling
vals[Matrix.MTRANS_X] = 0f;
vals[Matrix.MTRANS_Y] = 0f;
vals[Matrix.MSCALE_X] = 1f;
vals[Matrix.MSCALE_Y] = 1f;
save.setValues(vals);
return save;
}
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds.
*/
public void fitScreen() {
Matrix save = new Matrix();
save.set(mMatrixTouch);
float[] vals = new float[9];
save.getValues(vals);
// reset all translations and scaling
vals[Matrix.MTRANS_X] = 0f;
vals[Matrix.MTRANS_Y] = 0f;
vals[Matrix.MSCALE_X] = 1f;
vals[Matrix.MSCALE_Y] = 1f;
save.setValues(vals);
refreshTouch(save);
}
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds.
*/
public Matrix fitScreen() {
mMinScaleX = 1f;
mMinScaleY = 1f;
Matrix save = new Matrix();
save.set(mMatrixTouch);
float[] vals = new float[9];
save.getValues(vals);
// reset all translations and scaling
vals[Matrix.MTRANS_X] = 0f;
vals[Matrix.MTRANS_Y] = 0f;
vals[Matrix.MSCALE_X] = 1f;
vals[Matrix.MSCALE_Y] = 1f;
save.setValues(vals);
return save;
}
/**
* 检查是否越界
* @param matrix
*/
protected void checkBoundary(Matrix matrix) {
if (matrix == null) return;
matrix.getValues(mMXValues);
// 计算缩放是否小于要截取的大小
float size = mImgBitmap.getWidth() < mImgBitmap.getHeight() ? mImgBitmap.getWidth() : mImgBitmap.getHeight();
if (mMXValues[0] < mCircleRadius * 2 / size || mMXValues[4] < mCircleRadius * 2 / size) {
mMXValues[0] = mCircleRadius * 2 / size;
mMXValues[4] = mCircleRadius * 2 / size;
}
// 计算位移是否越界
if (mMXValues[2] > getWidth() / 2 - mCircleRadius) {
mMXValues[2] = getWidth() / 2 - mCircleRadius;
}
if (mMXValues[5] > getHeight() / 2 - mCircleRadius) {
mMXValues[5] = getHeight() / 2 - mCircleRadius;
}
if (mMXValues[2] < - mImgBitmap.getWidth() * mMXValues[0] + getWidth() / 2 + mCircleRadius) {
mMXValues[2]= - mImgBitmap.getWidth() * mMXValues[0] + getWidth() / 2 + mCircleRadius;
}
if (mMXValues[5] < - mImgBitmap.getHeight() * mMXValues[4] + getHeight() / 2 + mCircleRadius) {
mMXValues[5]= - mImgBitmap.getHeight() * mMXValues[4] + getHeight() / 2 + mCircleRadius;
}
matrix.setValues(mMXValues);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
mAnimRect.left = mStartCropWindowRect.left + (mEndCropWindowRect.left - mStartCropWindowRect.left) * interpolatedTime;
mAnimRect.top = mStartCropWindowRect.top + (mEndCropWindowRect.top - mStartCropWindowRect.top) * interpolatedTime;
mAnimRect.right = mStartCropWindowRect.right + (mEndCropWindowRect.right - mStartCropWindowRect.right) * interpolatedTime;
mAnimRect.bottom = mStartCropWindowRect.bottom + (mEndCropWindowRect.bottom - mStartCropWindowRect.bottom) * interpolatedTime;
mCropOverlayView.setCropWindowRect(mAnimRect);
for (int i = 0; i < mAnimPoints.length; i++) {
mAnimPoints[i] = mStartBoundPoints[i] + (mEndBoundPoints[i] - mStartBoundPoints[i]) * interpolatedTime;
}
mCropOverlayView.setBounds(mAnimPoints, mImageView.getWidth(), mImageView.getHeight());
for (int i = 0; i < mAnimMatrix.length; i++) {
mAnimMatrix[i] = mStartImageMatrix[i] + (mEndImageMatrix[i] - mStartImageMatrix[i]) * interpolatedTime;
}
Matrix m = mImageView.getImageMatrix();
m.setValues(mAnimMatrix);
mImageView.setImageMatrix(m);
mImageView.invalidate();
mCropOverlayView.invalidate();
}
/**
* OpenGLの4x4(列優先)行列をandroid.graphics.Matrixの3x3行列に変換する
* (アフィン変換のみ)
* @param transform
* @param result
* @param aMatrix
* @return
*/
public static Matrix toAndroidMatrix(
@NonNull @Size(min=16)final float[] transform,
@NonNull final Matrix result,
@NonNull @Size(min=9) final float[] aMatrix) {
aMatrix[Matrix.MSCALE_X] = transform[ 0];
aMatrix[Matrix.MSKEW_Y] = transform[ 1];
aMatrix[Matrix.MPERSP_0] = transform[ 3];
aMatrix[Matrix.MSKEW_X] = transform[ 4];
aMatrix[Matrix.MSCALE_Y] = transform[ 5];
aMatrix[Matrix.MPERSP_1] = transform[ 7];
aMatrix[Matrix.MTRANS_X] = transform[12];
aMatrix[Matrix.MTRANS_Y] = transform[13];
aMatrix[Matrix.MPERSP_2] = transform[15];
result.setValues(aMatrix);
return result;
}
private Matrix glMatrixToGraphicsMatrix(float[] glMatrix) {
float[] convert = new float[9];
convert[0] = glMatrix[0];
convert[1] = glMatrix[4];
convert[2] = glMatrix[12];
convert[3] = glMatrix[1];
convert[4] = glMatrix[5];
convert[5] = glMatrix[13];
convert[6] = glMatrix[3];
convert[7] = glMatrix[7];
convert[8] = glMatrix[15];
Matrix graphicsMatrix = new Matrix();
graphicsMatrix.setValues(convert);
return graphicsMatrix;
}
public static Matrix adjustClipMatrix(Context context, Matrix matrix) {
float scale = 1; // <------- 像素密度
// 获取手机像素密度 (即dp与px的比例)
scale = context.getResources().getDisplayMetrics().density;
float[] mValues = new float[9];
matrix.getValues(mValues); //获取数值
// if (mValues[6] < 0)
mValues[6] =0; //数值修正 发现这个数是负数就得修正;
// if (mValues[7] < 0)
mValues[7] = 0; //数值修正
matrix.setValues(mValues); //重新赋值
return matrix;
}
/**
* limits the maximum scale and X translation of the given matrix
*
* @param matrix
*/
public void limitTransAndScale(Matrix matrix, RectF content) {
matrix.getValues(matrixBuffer);
float curTransX = matrixBuffer[Matrix.MTRANS_X];
float curScaleX = matrixBuffer[Matrix.MSCALE_X];
float curTransY = matrixBuffer[Matrix.MTRANS_Y];
float curScaleY = matrixBuffer[Matrix.MSCALE_Y];
// min scale-x is 1f
mScaleX = Math.min(Math.max(mMinScaleX, curScaleX), mMaxScaleX);
// min scale-y is 1f
mScaleY = Math.min(Math.max(mMinScaleY, curScaleY), mMaxScaleY);
float width = 0f;
float height = 0f;
if (content != null) {
width = content.width();
height = content.height();
}
float maxTransX = -width * (mScaleX - 1f);
mTransX = Math.min(Math.max(curTransX, maxTransX - mTransOffsetX), mTransOffsetX);
float maxTransY = height * (mScaleY - 1f);
mTransY = Math.max(Math.min(curTransY, maxTransY + mTransOffsetY), -mTransOffsetY);
matrixBuffer[Matrix.MTRANS_X] = mTransX;
matrixBuffer[Matrix.MSCALE_X] = mScaleX;
matrixBuffer[Matrix.MTRANS_Y] = mTransY;
matrixBuffer[Matrix.MSCALE_Y] = mScaleY;
matrix.setValues(matrixBuffer);
}
/**
* limits the maximum scale and X translation of the given matrix
*
* @param matrix
*/
public void limitTransAndScale(Matrix matrix, RectF content) {
matrix.getValues(matrixBuffer);
float curTransX = matrixBuffer[Matrix.MTRANS_X];
float curScaleX = matrixBuffer[Matrix.MSCALE_X];
float curTransY = matrixBuffer[Matrix.MTRANS_Y];
float curScaleY = matrixBuffer[Matrix.MSCALE_Y];
// min scale-x is 1f
mScaleX = Math.min(Math.max(mMinScaleX, curScaleX), mMaxScaleX);
// min scale-y is 1f
mScaleY = Math.min(Math.max(mMinScaleY, curScaleY), mMaxScaleY);
float width = 0f;
float height = 0f;
if (content != null) {
width = content.width();
height = content.height();
}
float maxTransX = -width * (mScaleX - 1f);
mTransX = Math.min(Math.max(curTransX, maxTransX - mTransOffsetX), mTransOffsetX);
float maxTransY = height * (mScaleY - 1f);
mTransY = Math.max(Math.min(curTransY, maxTransY + mTransOffsetY), -mTransOffsetY);
matrixBuffer[Matrix.MTRANS_X] = mTransX;
matrixBuffer[Matrix.MSCALE_X] = mScaleX;
matrixBuffer[Matrix.MTRANS_Y] = mTransY;
matrixBuffer[Matrix.MSCALE_Y] = mScaleY;
matrix.setValues(matrixBuffer);
}
/**
* limits the maximum scale and X translation of the given matrix
*
* @param matrix
*/
public void limitTransAndScale(Matrix matrix, RectF content) {
matrix.getValues(matrixBuffer);
float curTransX = matrixBuffer[Matrix.MTRANS_X];
float curScaleX = matrixBuffer[Matrix.MSCALE_X];
float curTransY = matrixBuffer[Matrix.MTRANS_Y];
float curScaleY = matrixBuffer[Matrix.MSCALE_Y];
// min scale-x is 1f
mScaleX = Math.min(Math.max(mMinScaleX, curScaleX), mMaxScaleX);
// min scale-y is 1f
mScaleY = Math.min(Math.max(mMinScaleY, curScaleY), mMaxScaleY);
float width = 0f;
float height = 0f;
if (content != null) {
width = content.width();
height = content.height();
}
float maxTransX = -width * (mScaleX - 1f);
mTransX = Math.min(Math.max(curTransX, maxTransX - mTransOffsetX), mTransOffsetX);
float maxTransY = height * (mScaleY - 1f);
mTransY = Math.max(Math.min(curTransY, maxTransY + mTransOffsetY), -mTransOffsetY);
matrixBuffer[Matrix.MTRANS_X] = mTransX;
matrixBuffer[Matrix.MSCALE_X] = mScaleX;
matrixBuffer[Matrix.MTRANS_Y] = mTransY;
matrixBuffer[Matrix.MSCALE_Y] = mScaleY;
matrix.setValues(matrixBuffer);
}
public void syncCharts() {
Matrix srcMatrix;
float[] srcVals = new float[9];
Matrix dstMatrix;
float[] dstVals = new float[9];
// get src chart translation matrix:
srcMatrix = srcChart.getViewPortHandler().getMatrixTouch();
srcMatrix.getValues(srcVals);
// apply X axis scaling and position to dst charts:
for (Chart dstChart : dstCharts) {
dstMatrix = dstChart.getViewPortHandler().getMatrixTouch();
dstMatrix.getValues(dstVals);
dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
dstVals[Matrix.MSKEW_X] = srcVals[Matrix.MSKEW_X];
dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
dstVals[Matrix.MSKEW_Y] = srcVals[Matrix.MSKEW_Y];
dstVals[Matrix.MSCALE_Y] = srcVals[Matrix.MSCALE_Y];
dstVals[Matrix.MTRANS_Y] = srcVals[Matrix.MTRANS_Y];
dstVals[Matrix.MPERSP_0] = srcVals[Matrix.MPERSP_0];
dstVals[Matrix.MPERSP_1] = srcVals[Matrix.MPERSP_1];
dstVals[Matrix.MPERSP_2] = srcVals[Matrix.MPERSP_2];
dstMatrix.setValues(dstVals);
dstChart.getViewPortHandler().refresh(dstMatrix, dstChart, true);
}
}
/**
* limits the maximum scale and X translation of the given matrix
*
* @param matrix
*/
public void limitTransAndScale(Matrix matrix, RectF content) {
matrix.getValues(matrixBuffer);
float curTransX = matrixBuffer[Matrix.MTRANS_X];
float curScaleX = matrixBuffer[Matrix.MSCALE_X];
float curTransY = matrixBuffer[Matrix.MTRANS_Y];
float curScaleY = matrixBuffer[Matrix.MSCALE_Y];
// min scale-x is 1f
mScaleX = Math.min(Math.max(mMinScaleX, curScaleX), mMaxScaleX);
// min scale-y is 1f
mScaleY = Math.min(Math.max(mMinScaleY, curScaleY), mMaxScaleY);
float width = 0f;
float height = 0f;
if (content != null) {
width = content.width();
height = content.height();
}
float maxTransX = -width * (mScaleX - 1f);
mTransX = Math.min(Math.max(curTransX, maxTransX - mTransOffsetX), mTransOffsetX);
float maxTransY = height * (mScaleY - 1f);
mTransY = Math.max(Math.min(curTransY, maxTransY + mTransOffsetY), -mTransOffsetY);
matrixBuffer[Matrix.MTRANS_X] = mTransX;
matrixBuffer[Matrix.MSCALE_X] = mScaleX;
matrixBuffer[Matrix.MTRANS_Y] = mTransY;
matrixBuffer[Matrix.MSCALE_Y] = mScaleY;
matrix.setValues(matrixBuffer);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
mCamera.save();
// 调节深度
if (mReverse) {
mCamera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
mCamera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
// 绕轴旋转
switch (mAxis) {
case 1:
mCamera.rotateX(degrees);
break;
case 2:
mCamera.rotateY(degrees);
break;
case 3:
mCamera.rotateZ(degrees);
break;
}
mCamera.getMatrix(matrix);
mCamera.restore();
// 修复失真
float[] mValues = new float[9];
matrix.getValues(mValues); //获取数值
mValues[6] = mValues[6] / scale; //数值修正
mValues[7] = mValues[7] / scale; //数值修正
matrix.setValues(mValues); //重新赋值
// 设置中心
matrix.preTranslate(-mCenterX, -mCenterY);
matrix.postTranslate(mCenterX, mCenterY);
}
/**
* Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
* matrix that is to be applied other positional data in this class.
* @return a new instance (copy) of the transformation matrix.
*/
public Matrix getMatrix() {
final Matrix matrix = new Matrix();
matrix.setValues(mMatrixValues);
return matrix;
}
ViewNode(ParcelTransferReader reader, int nestingLevel) {
final Parcel in = reader.readParcel(VALIDATE_VIEW_TOKEN, nestingLevel);
reader.mNumReadViews++;
final PooledStringReader preader = reader.mStringReader;
mClassName = preader.readString();
mFlags = in.readInt();
final int flags = mFlags;
if ((flags&FLAGS_HAS_ID) != 0) {
mId = in.readInt();
if (mId != View.NO_ID) {
mIdEntry = preader.readString();
if (mIdEntry != null) {
mIdType = preader.readString();
mIdPackage = preader.readString();
}
}
}
if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
mSanitized = in.readInt() == 1;
mAutofillId = in.readParcelable(null);
mAutofillType = in.readInt();
mAutofillHints = in.readStringArray();
mAutofillValue = in.readParcelable(null);
mAutofillOptions = in.readCharSequenceArray();
final Parcelable p = in.readParcelable(null);
if (p instanceof HtmlInfo) {
mHtmlInfo = (HtmlInfo) p;
}
mMinEms = in.readInt();
mMaxEms = in.readInt();
mMaxLength = in.readInt();
mTextIdEntry = preader.readString();
mImportantForAutofill = in.readInt();
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
mX = in.readInt();
mY = in.readInt();
mWidth = in.readInt();
mHeight = in.readInt();
} else {
int val = in.readInt();
mX = val&0x7fff;
mY = (val>>16)&0x7fff;
val = in.readInt();
mWidth = val&0x7fff;
mHeight = (val>>16)&0x7fff;
}
if ((flags&FLAGS_HAS_SCROLL) != 0) {
mScrollX = in.readInt();
mScrollY = in.readInt();
}
if ((flags&FLAGS_HAS_MATRIX) != 0) {
mMatrix = new Matrix();
in.readFloatArray(reader.mTmpMatrix);
mMatrix.setValues(reader.mTmpMatrix);
}
if ((flags&FLAGS_HAS_ELEVATION) != 0) {
mElevation = in.readFloat();
}
if ((flags&FLAGS_HAS_ALPHA) != 0) {
mAlpha = in.readFloat();
}
if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
}
if ((flags&FLAGS_HAS_TEXT) != 0) {
mText = new ViewNodeText(in, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
}
if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) {
mInputType = in.readInt();
}
if ((flags&FLAGS_HAS_URL) != 0) {
mWebScheme = in.readString();
mWebDomain = in.readString();
}
if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) {
mLocaleList = in.readParcelable(null);
}
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
mExtras = in.readBundle();
}
if ((flags&FLAGS_HAS_CHILDREN) != 0) {
final int NCHILDREN = in.readInt();
if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG,
"Preparing to read " + NCHILDREN
+ " children: @ #" + reader.mNumReadViews
+ ", level " + nestingLevel);
mChildren = new ViewNode[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
mChildren[i] = new ViewNode(reader, nestingLevel + 1);
}
}
}
public static void readMatrix(@NonNull Matrix matrix, @NonNull Parcel in) {
float[] values = new float[9];
in.readFloatArray(values);
matrix.setValues(values);
}
protected void calculateInterpolation(Matrix outMatrix, float fraction) {
for (int i = 0; i < 9; i++) {
mCurrentValues[i] = (1 - fraction) * mStartValues[i] + fraction * mStopValues[i];
}
outMatrix.setValues(mCurrentValues);
}
protected void calculateInterpolation(Matrix outMatrix, float fraction) {
for (int i = 0; i < 9; i++) {
mCurrentValues[i] = (1 - fraction) * mStartValues[i] + fraction * mStopValues[i];
}
outMatrix.setValues(mCurrentValues);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
// 生成中间角度
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
// 取得变换后的矩阵
camera.getMatrix(matrix);
camera.restore();
//----------------------------------------------------------------------------
/**
* 修复打脸问题 ( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)
* 简要介绍:
* 原来的3D翻转会由于屏幕像素密度问题而出现效果相差很大
* 例如在屏幕像素比为1,5的手机上显示效果基本正常,
* 而在像素比3,0的手机上面感觉翻转感觉要超出屏幕边缘,
* 有种迎面打脸的感觉、
*
* 解决方案
* 利用屏幕像素密度对变换矩阵进行校正,
* 保证了在所有清晰度的手机上显示的效果基本相同。
*
*/
float[] mValues = {0,0,0,0,0,0,0,0,0};
matrix.getValues(mValues); //获取数值
mValues[6] = mValues[6]/scale; //数值修正
matrix.setValues(mValues); //重新赋值
// Log.e("TAG", "mValues["+0+"]="+mValues[0]+"------------\t"+"mValues["+6+"]="+mValues[6]);
//----------------------------------------------------------------------------
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}