缩放自定义android TextureView

时间:2016-02-18 08:49:41

标签: android pinchzoom textureview

我正在使用具有缩放功能的自定义TextureView(适用于Android播放器)。问题是我不能做准确的缩放。当你第一次尝试放大时,似乎没有问题。在一些缩放视图跳转到另一个位置后。我将把自定义textureView代码放在这里:

public class PanZoomTextureView extends TextureView {

    protected Context mContext;
    protected float mPosX;
    protected float mPosY;

    protected float mFocusX;    // these two focus variables are not needed
    protected float mFocusY;

    protected float mLastTouchX;
    protected float mLastTouchY;

    protected static final int INVALID_POINTER_ID = -1;

    // The ‘active pointer’ is the one currently moving our object.
    protected int mActivePointerId = INVALID_POINTER_ID;

    protected ScaleGestureDetector mScaleDetector;
    protected float mScaleFactor = 1.f;

    // The next three are set by calling supportsPan, supportsZoom, ...
    protected boolean mSupportsPan = true;
    protected boolean mSupportsZoom = true;
    private MediaController controller;


    /**
     */
    public PanZoomTextureView(Context context) {
        this(context, null, 0);
    }

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

    public PanZoomTextureView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        setupScaleDetector(context);
    }

    private void invalidateDraw() {
        Matrix ma = new Matrix();

        float x = 0, y = 0;

        x = mPosX;

        y = mPosY;

        if (mSupportsZoom || mSupportsPan) {

            if (mSupportsPan && mSupportsZoom) {

                if (mScaleDetector.isInProgress()) {

                    ma.setScale(mScaleFactor, mScaleFactor, mFocusX, mFocusY);

                    mPosX = (getWidth() - getWidth() * mScaleFactor) * (mFocusX / getWidth()) / 2;

                    mPosY = (getHeight() - getHeight() * mScaleFactor) * (mFocusY / getHeight()) / 2;

                    Log.d("Multitouch", "'in progress' mposx, mposy, focusX, focusY: " + mPosX + " " + mPosY + " " + mFocusX + " " + mFocusY);

                } else {

                    // Pinch zoom is not in progress. Just do translation
                    // of canvas at whatever the current scale is.
                    ma.setTranslate(x, y);

                    ma.postScale(mScaleFactor, mScaleFactor);

                    Log.d("Multitouch", "x, y , focusX, focusY , scalefactor : " + x + " " + y + " " + mFocusX + " " + mFocusY + " " + mScaleFactor);
                }
            }
        }

        setTransform(ma);
    }

    public void setMediaController(MediaController c) {
        this.controller = c;
    }

    /**
     * Handle touch and multitouch events so panning and zooming can be supported.
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        // Let the ScaleGestureDetector inspect all events.
        mScaleDetector.onTouchEvent(ev);

        final int action = ev.getAction();

        switch (action & MotionEvent.ACTION_MASK) {

            case MotionEvent.ACTION_DOWN: {

                final float x = ev.getX();
                final float y = ev.getY();

                mLastTouchX = x;
                mLastTouchY = y;

                mActivePointerId = ev.getPointerId(0);

                Log.d("OnTouchDown:", "lastX, lastY: " + mLastTouchX + "  ,  " + mLastTouchY);

                if (ev.getPointerCount() == 1) {
                    if (controller.isShowing()) {

                        controller.hide();

                    } else {
                        controller.show(10000);
                    }
                }

                break;
            }

            case MotionEvent.ACTION_MOVE: {
                //register active pointer index
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);

                // x and y values from active pointer
                final float x = ev.getX(pointerIndex);
                final float y = ev.getY(pointerIndex);

                final float dx = (x - mLastTouchX);

                final float dy = (y - mLastTouchY);

                // Only move if the view supports panning and
                // ScaleGestureDetector isn't processing a gesture.
                if (!mScaleDetector.isInProgress()) {

                    Log.d("OnTouch1:", "dX, dY: " + dx + "  ,  " + dy);

                    if (mPosX > 5) {
                        mPosX = 3;
                    }

                    if (mPosY > 5) {
                        mPosY = 3;
                    }

                    if (mPosX < ((-1) * (getWidth() - getWidth() / mScaleFactor) - 5)) {

                        mPosX = ((-1) * (getWidth() - getWidth() / mScaleFactor) - 2);
                    }
                    if (mPosY < ((-1) * (getHeight() - getHeight() / mScaleFactor) - 5)) {

                        mPosY = ((-1) * (getHeight() - getHeight() / mScaleFactor) - 2);

                    }
                    if ((mPosX + dx) > 5 && (mPosY + dy) > 5) {

                        mPosX = 3;
                        mPosY = 3;
                        Log.d("OnTouch1:", "mPosx, mPosy: " + mPosX + "  ,  " + mPosY);

                    } else if ((mPosY + dy) > 5 && (mPosX + dx) < 5 && (mPosX + dx) > ((-1) * (getWidth() - getWidth() / mScaleFactor) - 5)) {

                        mPosY = 3;

                        mPosX += dx;

                        Log.d("OnTouch2:", "mPosx, mPosy: " + mPosX + "  ,  " + mPosY);

                    } else {
                        mPosX += dx;
                        mPosY += dy;
                        Log.d("OnTouch8:", "mPosx, mPosy: " + mPosX + "  ,  " + mPosY);
                    }

                    invalidateDraw();
                }
                mLastTouchX = x;
                mLastTouchY = y;
                break;
            }

            case MotionEvent.ACTION_UP: {

                mActivePointerId = INVALID_POINTER_ID;

                break;
            }

            case MotionEvent.ACTION_CANCEL: {

                mActivePointerId = INVALID_POINTER_ID;

                break;
            }

            case MotionEvent.ACTION_POINTER_UP: {

                final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;

                final int pointerId = ev.getPointerId(pointerIndex);

                if (pointerId == mActivePointerId) {

                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;

                    mLastTouchX = ev.getX(newPointerIndex);

                    mLastTouchY = ev.getY(newPointerIndex);

                    mActivePointerId = ev.getPointerId(newPointerIndex);

                }

                break;
            }
        }

        return true;
    }

    /**
     * This method sets up the scale detector object used by the view. It is called by the constructor.
     *
     * @return void
     */

    protected void setupScaleDetector(Context context) {
        // Create our ScaleGestureDetector
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());

    }

    /**
     * ScaleListener
     */
    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            mScaleFactor *= detector.getScaleFactor();
            Log.e("Multitouch", "-------scaling factor:" + mScaleFactor);
            // Don't let the object get too small or too large.
            mScaleFactor = Math.max(1.f, Math.min(mScaleFactor, 4));

            mFocusX = detector.getFocusX();
            mFocusY = detector.getFocusY();


            invalidateDraw();

            return true;
        }
    }
}

此外,如果有人想在这里测试真实项目,请链接:https://github.com/Shuhrat-java/PanZoomPlayer

0 个答案:

没有答案