Java tutorial
//package com.java2s; /* * Copyright (C) 2016 Zheng Li <https://lizheng.me> * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.graphics.Matrix; import android.graphics.RectF; import android.view.View; import java.util.ArrayList; public class Main { public static Matrix IDENTITY_MATRIX = new Matrix() { void oops() { throw new IllegalStateException("Matrix can not be modified"); } @Override public void set(Matrix src) { oops(); } @Override public void reset() { oops(); } @Override public void setTranslate(float dx, float dy) { oops(); } @Override public void setScale(float sx, float sy, float px, float py) { oops(); } @Override public void setScale(float sx, float sy) { oops(); } @Override public void setRotate(float degrees, float px, float py) { oops(); } @Override public void setRotate(float degrees) { oops(); } @Override public void setSinCos(float sinValue, float cosValue, float px, float py) { oops(); } @Override public void setSinCos(float sinValue, float cosValue) { oops(); } @Override public void setSkew(float kx, float ky, float px, float py) { oops(); } @Override public void setSkew(float kx, float ky) { oops(); } @Override public boolean setConcat(Matrix a, Matrix b) { oops(); return false; } @Override public boolean preTranslate(float dx, float dy) { oops(); return false; } @Override public boolean preScale(float sx, float sy, float px, float py) { oops(); return false; } @Override public boolean preScale(float sx, float sy) { oops(); return false; } @Override public boolean preRotate(float degrees, float px, float py) { oops(); return false; } @Override public boolean preRotate(float degrees) { oops(); return false; } @Override public boolean preSkew(float kx, float ky, float px, float py) { oops(); return false; } @Override public boolean preSkew(float kx, float ky) { oops(); return false; } @Override public boolean preConcat(Matrix other) { oops(); return false; } @Override public boolean postTranslate(float dx, float dy) { oops(); return false; } @Override public boolean postScale(float sx, float sy, float px, float py) { oops(); return false; } @Override public boolean postScale(float sx, float sy) { oops(); return false; } @Override public boolean postRotate(float degrees, float px, float py) { oops(); return false; } @Override public boolean postRotate(float degrees) { oops(); return false; } @Override public boolean postSkew(float kx, float ky, float px, float py) { oops(); return false; } @Override public boolean postSkew(float kx, float ky) { oops(); return false; } @Override public boolean postConcat(Matrix other) { oops(); return false; } @Override public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) { oops(); return false; } @Override public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) { oops(); return false; } @Override public void setValues(float[] values) { oops(); } }; /** * Maps a coordinate in the root to a descendent. */ public static float mapCoordInSelfToDescendent(View descendant, View root, float[] coord, Matrix tmpInverseMatrix) { ArrayList<View> ancestorChain = new ArrayList<>(); float[] pt = { coord[0], coord[1] }; View v = descendant; while (v != root) { ancestorChain.add(v); v = (View) v.getParent(); } ancestorChain.add(root); float scale = 1.0f; int count = ancestorChain.size(); tmpInverseMatrix.set(IDENTITY_MATRIX); for (int i = count - 1; i >= 0; i--) { View ancestor = ancestorChain.get(i); View next = i > 0 ? ancestorChain.get(i - 1) : null; pt[0] += ancestor.getScrollX(); pt[1] += ancestor.getScrollY(); if (next != null) { pt[0] -= next.getLeft(); pt[1] -= next.getTop(); next.getMatrix().invert(tmpInverseMatrix); tmpInverseMatrix.mapPoints(pt); scale *= next.getScaleX(); } } coord[0] = pt[0]; coord[1] = pt[1]; return scale; } }