參考:
3、Android中關於矩陣(Matrix)前乘后乘的一些認識
View.setPivotX:設置旋轉或縮放的基點的X位置,默認是對象的中點(官方API說明:https://developer.android.com/reference/android/view/View.html#setPivotX(float))。
View.setScaleX:設置縮放比例。一般情況下,View的縮放會產生平移數據。
相對點P(a,b)的比例[sx,sy]變化矩陣[1]
這里的點P(a, b)就是前文說的基點。
注意:
setTranslationX(),是post模式,即setTranslationX()產生的變換矩陣乘以當前矩陣。
setScaleX(),使pre模式,即當前矩陣乘以setScaleX()產生的變換矩陣。
例子:
無論setScalex()在setTanslation()之前或之后調用,都是setTanslation()產生的變換矩陣乘以setScaleX()產生的變換矩陣。
舉例:setScalex(0.9),setTanslation(100),矩陣變換為:
1 0 100 乘以 0.9 0 (1-0.9)*320 得到 0.9 0 132
0 1 0 0 1 0 0 1 0
0 0 1 0 0 1 0 0 1
第一個矩陣由setTanslation(100)得到,第二個矩陣由setScalex(0.9)得到,而(1-0.9)*320中的320是Image中點X值,實例圖片寬度為640。
再次調用這兩個方法后,都是重新進行計算,而不是在前一次的基礎上計算。都是從矩陣 1 0 0 開始。
0 1 0
0 0 1
代碼:
public class MatrixActivity extends Activity implements View.OnClickListener { private static final String TAG = MatrixActivity.class.getSimpleName(); private ImageView mWImageView; private Button mBtn_Translation, mBtnScale, mBtnTranslation; private int mHeight, mWidth; private static float mScale = 1.0f; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_matrix); mWImageView = (ImageView) findViewById(R.id.welcome_img_view); mBtn_Translation = (Button) findViewById(R.id._translation); mBtnScale = (Button) findViewById(R.id.scale); mBtnTranslation = (Button) findViewById(R.id.translation); //改變基點的X值,默認以中點 // mWImageView.setPivotX(0); // mWImageView.setPivotX(640); setOnclickListener(); } @Override protected void onResume() { Log.d(TAG, "In onResume ---------------------"); super.onResume(); publicLog(); } private void setOnclickListener() { mBtn_Translation.setOnClickListener(this); mBtnScale.setOnClickListener(this); mBtnTranslation.setOnClickListener(this); } private void publicLog() { Log.d(TAG, "mWImageView x, y, width, height:" + mWImageView.getLeft() + " --- " + mWImageView.getTop() + " --- " + mWImageView.getWidth() + " --- " + mWImageView.getHeight()); Log.d(TAG, "mWImageView Pivots:" + mWImageView.getPivotX() + " --- " + mWImageView.getPivotY()); Log.d(TAG, "mWImageView Matrix:" + mWImageView.getMatrix()); } @Override public void onClick(View v) { int id = v.getId(); mHeight = mWImageView.getHeight(); mWidth = mWImageView.getWidth(); int dx = mWidth / 2; switch (id) { case R.id._translation: Log.d(TAG, "mWImageView _translation ---------------------"); publicLog(); Log.d(TAG, "mWImageView TranslationX: " + -dx); mWImageView.setTranslationX(-dx); publicLog(); break; case R.id.scale: Log.d(TAG, "mWImageView scale ---------------------"); publicLog(); if(mScale - 0.1 > 0){ mScale = mScale - 0.1f; }else{ mScale = mScale + 0.1f; } mWImageView.setScaleX(mScale); publicLog(); break; case R.id.translation: Log.d(TAG, "mWImageView translation ---------------------"); publicLog(); Log.d(TAG, "mWImageView TranslationX: " + dx); mWImageView.setTranslationX(dx); publicLog(); break; } int[] location = new int[2]; mWImageView.getLocationInWindow(location); Log.d(TAG, "mWImageView LocationInWindow:" + location[0] + " --- " + location[1]); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/welcome_img_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/welcome" /> <Button android:id="@+id/_translation" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" - Translation " /> <Button android:id="@+id/scale" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Scale" /> <Button android:id="@+id/translation" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Translation " /> </LinearLayout>

