ImageViewのsetImageMatrixは、一部のデバイスでは正しく機能しません(Android 4.4より古い可能性があります)

レオ

このコードでタッチイベントのImageViewを移動しようとしました:

public class ScrollableImageView extends ImageView {
    private GestureDetectorCompat gestureDetectorCompat;

    public ScrollableImageView(Context context) {
        this(context, null);
    }

    public ScrollableImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ScaleType.MATRIX);

        gestureDetectorCompat = new GestureDetectorCompat(context,
                new MySimpleOnGestureListener(this));
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        gestureDetectorCompat.onTouchEvent(event);
        return true;
    }

    public void scroll(float distance) {
        Matrix imageMatrix = getImageMatrix();
        imageMatrix.postTranslate(distance, 0);
        setImageMatrix(imageMatrix);
        invalidate();
    }

    private static class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
        private ScrollableImageView scrollableImageView;

        public MySimpleOnGestureListener(ScrollableImageView scrollableImageView) {
            this.scrollableImageView = scrollableImageView;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            Utils.log("onDown");
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            scrollableImageView.scroll(-distanceX);
            return true;
        }
    }
}

最初は、すべてがNexus 5(Android 4.4.4およびLollipop)でうまく機能していました。しかし、4.0.4(Galaxy S2)やNexus S(4.1.1)などの古いバージョンのAndroidを試してみましたが、どれも機能しませんでした。

それからしばらく苦労した後、私はこの解決策を思いつきました、そしてそれはすべてのデバイスでうまくいきました:

(現在、ImageViewのgetImageMatrix()を介して取得するのではなく、ローカルオブジェクトによってImageViewのマトリックスオブジェクトを追跡していることに注意してください)

public class ScrollableImageView extends ImageView {
    private GestureDetectorCompat gestureDetectorCompat;
    private Matrix imageMatrix;

    public ScrollableImageView(Context context) {
        this(context, null);
    }

    public ScrollableImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ScaleType.MATRIX);

        imageMatrix = new Matrix();

        gestureDetectorCompat = new GestureDetectorCompat(context,
                new MySimpleOnGestureListener(this));
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        gestureDetectorCompat.onTouchEvent(event);
        return true;
    }

    public void scroll(float distance) {
        imageMatrix.postTranslate(distance, 0);
        setImageMatrix(imageMatrix);
        invalidate();
    }

    private static class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
        private ScrollableImageView scrollableImageView;

        public MySimpleOnGestureListener(ScrollableImageView scrollableImageView) {
            this.scrollableImageView = scrollableImageView;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            Utils.log("onDown");
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            scrollableImageView.scroll(-distanceX);
            return true;
        }
    }
}

私は解決策を手に入れましたが、以前のコードが機能しなかった理由をまだ理解できませんでしたか?!

私は調査しようとしましたが、理にかなっているのはImageViewのgetImageMatrix()のドキュメントだけでした。

ビューのオプションのマトリックスを返します。これは、ビューが描画されるときにビューのドローアブルに適用されます。行列がない場合、このメソッドは単位行列を返します。このマトリックスをその場で変更せずに、コピーを作成してください。ドローアブルに別のマトリックスを適用する場合は、必ずsetImageMatrix()を呼び出してください。

それから、それは私をもっと混乱させましたDo not change this matrix in place but make a copy、そうすることのポイントは何ですか?以前のコードで行ったようにできないのはなぜですか?(ImageViewの現在のマトリックスを取得してから変換を適用し、ドキュメントに記載されているようにsetImageMatrix()を介して元に戻します)

誰かが私にいくつかの光を当ててください、これは私にとってあまりにも多くの混乱です。

レオ

わかった、みんな、わかった!

実際、ドキュメントは理にかなっています。

ビューのオプションのマトリックスを返します。これは、ビューが描画されるときにビューのドローアブルに適用されます。行列がない場合、このメソッドは単位行列を返します。このマトリックスをその場で変更せずに、コピーを作成してくださいドローアブルに別のマトリックスを適用する場合は、必ずsetImageMatrix()を呼び出してください。

ics_mr1のImageViewソースコードにこのコードがあるため:

public void setImageMatrix(Matrix matrix) {
    // collaps null and identity to just null
    if (matrix != null && matrix.isIdentity()) {
        matrix = null;
    }

    // don't invalidate unless we're actually changing our matrix
    if (matrix == null && !mMatrix.isIdentity() ||
            matrix != null && !mMatrix.equals(matrix)) {
        mMatrix.set(matrix);
        configureBounds();
        invalidate();
    }
}

だから私が好きなら:

   Matrix imageMatrix = getImageMatrix();
   imageMatrix.postTranslate(distance, 0);
   setImageMatrix(imageMatrix);

matrix != null && !mMatrix.equals(matrix)なりますfalse私は(ドキュメントが言った理由のがいるのと同じMatrixオブジェクトを再利用するためDo not change this matrix in place but make a copyの条件のいずれも満たしていないため)、その後、何も起こらないだろう。

それから今、私ははるかにエレガントな解決策を思いつきます:

   Matrix imageMatrix = new Matrix(getImageMatrix());
   imageMatrix.postTranslate(distance, 0);
   setImageMatrix(imageMatrix);

それは
YIKESです

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

TOP 一覧

  1. 1

    PyCharmリモートインタープリターはプロジェクトタブにサイトパッケージのコンテンツを表示しません

  2. 2

    <p:fieldset>の凡例に<h1>、<h2>タグを配置するにはどうすればよいですか?

  3. 3

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  4. 4

    パンダは異なる名前の列に追加します

  5. 5

    Railsで宝石のレイアウトを使用するにはどうすればよいですか?

  6. 6

    Java文字列の仕組み

  7. 7

    Chromeウェブアプリのウェブビューの高さの問題

  8. 8

    CSSのみを使用して三角形のアニメーションを作成する方法

  9. 9

    httpListenerコールバックが2回呼び出されます

  10. 10

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  11. 11

    初期化時にextern / static変数のタイプを指定する必要があるのはなぜですか?

  12. 12

    ファイルがgitlfsに正しくアップロードされるかどうかを確認するにはどうすればよいですか?

  13. 13

    Grouping data with datatable with ASP.NET

  14. 14

    Ecto - migrate table column into its own join table (shifting the DATA to the new tables)

  15. 15

    Crashlytics:コンパイラー生成とはどういう意味ですか?

  16. 16

    Python / SciPyのピーク検出アルゴリズム

  17. 17

    PictureBoxで画像のブレンドを無効にする

  18. 18

    ディスパッチ不可能なハンドルが64ビットプラットフォームでptrを使用するのはなぜですか?

  19. 19

    アクティブな管理者で関連するモデルのドロップダウンメニューの問題を解決する方法

  20. 20

    Windows 7では、一部のプログラムは「ビジュアルテーマを無効にする」レジストリ設定を行いませんか?

  21. 21

    文字列内のすべての単語に一致する正規表現

ホットタグ

アーカイブ