Как реализовать Touch слушателя и ущипнуть зум на одном экране? - PullRequest
2 голосов
/ 27 октября 2019

Я хочу реализовать сенсорный приемник для перемещения вида и масштабирования пинч для увеличения, но когда я касаюсь вида пальцами для масштабирования, работает только сенсорный приемник. Я не могу справиться с пинч-масштабированием должным образом. Пожалуйста, помогите мне, поскольку я понятия не имею, как это реализовать. Я пробовал все, но не могу решить эту проблему.

xml:

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher_foreground" />

java-код:

public class ExperimentActivity extends AppCompatActivity {

    private static final String TAG = ExperimentActivity.class.getSimpleName();

    LinearLayout mRootView;
    ImageView mImageView;

    private ScaleGestureDetector mScaleGestureDetector;
    private float mScaleFactor = 1.0f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_experiment);

        mRootView = findViewById(R.id.rootView);
        mImageView = findViewById(R.id.image_view);
        mImageView.setOnTouchListener(onTouchListener());
        mScaleGestureDetector = new ScaleGestureDetector(ExperimentActivity.this, new ScaleListener());
    }

    public boolean onTouchEvent(MotionEvent motionEvent) {
        mScaleGestureDetector.onTouchEvent(motionEvent);
        return true;
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector scaleGestureDetector){
            mScaleFactor *= scaleGestureDetector.getScaleFactor();
            mScaleFactor = Math.max(0.5f, Math.min(mScaleFactor, 1.1f));
            int w = (int) (mImageView.getWidth() * mScaleFactor);
            int h = (int) (mImageView.getHeight() * mScaleFactor);
            w = Math.min(450, Math.max(80, w));
            h = Math.min(450, Math.max(80, h));
            mImageView.setLayoutParams(new LinearLayout.LayoutParams(w, h));
            return true;
        }
    }

    private View.OnTouchListener onTouchListener() {
        return new View.OnTouchListener() {

            @SuppressLint("ClickableViewAccessibility")
            float dX, dY;
            int lastAction;

            @Override
            public boolean onTouch(View view, MotionEvent event) {

                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        dX = view.getX() - event.getRawX();
                        dY = view.getY() - event.getRawY();
                        lastAction = MotionEvent.ACTION_DOWN;
                        break;

                    case MotionEvent.ACTION_MOVE:
                        view.setY(event.getRawY() + dY);
                        view.setX(event.getRawX() + dX);
                        lastAction = MotionEvent.ACTION_MOVE;
                        break;

                    case MotionEvent.ACTION_UP:
                        if (lastAction == MotionEvent.ACTION_DOWN)
                            Toast.makeText(ExperimentActivity.this, "Clicked!", Toast.LENGTH_SHORT).show();
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        dX = view.getX() - event.getRawX();
                        dY = view.getY() - event.getRawY();
                        lastAction = MotionEvent.ACTION_POINTER_DOWN;
                        mScaleGestureDetector = new ScaleGestureDetector(ExperimentActivity.this, new ScaleListener());
                        break;
                    default:
                        return false;
                }
                return true;
            }
        };
    }

}

1 Ответ

0 голосов
/ 29 октября 2019

Попробуйте обновить код следующим образом.

public class ExperimentActivity extends AppCompatActivity {

private static final String TAG = ExperimentActivity.class.getSimpleName();

LinearLayout mRootView;
ImageView mImageView;

private ScaleGestureDetector mScaleGestureDetector;
private float mScaleFactor = 1.0f;
private Handler mHandler;
private boolean pinchToZoom;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    mHandler = new Handler();
    mRootView = findViewById(R.id.rootView);
    mImageView = findViewById(R.id.image_view);
    mImageView.setOnTouchListener(onTouchListener());
    mScaleGestureDetector = new ScaleGestureDetector(ExperimentActivity.this, new ScaleListener());
}

public boolean onTouchEvent(MotionEvent motionEvent) {
    mScaleGestureDetector.onTouchEvent(motionEvent);
    return true;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
        mScaleFactor *= scaleGestureDetector.getScaleFactor();
        mScaleFactor = Math.max(0.5f, Math.min(mScaleFactor, 2.0f));
        int w = (int) (mImageView.getWidth() * mScaleFactor);
        int h = (int) (mImageView.getHeight() * mScaleFactor);
        w = Math.min(900, Math.max(80, w));
        h = Math.min(900, Math.max(80, h));
        mImageView.setLayoutParams(new LinearLayout.LayoutParams(w, h));

        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        pinchToZoom = true;
        return super.onScaleBegin(detector);
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        resetFlag();
        super.onScaleEnd(detector);
    }
}

private void resetFlag() {
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            pinchToZoom = false;
        }
    }, 500);
}

private View.OnTouchListener onTouchListener() {
    return new View.OnTouchListener() {
        float dX, dY;
        int lastAction;

        @Override
        public boolean onTouch(View view, MotionEvent event) {

            switch (event.getActionMasked()) {

                case MotionEvent.ACTION_DOWN:
                    dX = view.getX() - event.getRawX();
                    dY = view.getY() - event.getRawY();
                    lastAction = MotionEvent.ACTION_DOWN;
                    break;

                case MotionEvent.ACTION_MOVE:
                    onTouchEvent(event);
                    if (!pinchToZoom) {
                        view.setY(event.getRawY() + dY);
                        view.setX(event.getRawX() + dX);
                        lastAction = MotionEvent.ACTION_MOVE;
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    mHandler.removeCallbacksAndMessages(null);
                    pinchToZoom = false;
                    break;

                case MotionEvent.ACTION_POINTER_DOWN:
                    dX = view.getX() - event.getRawX();
                    dY = view.getY() - event.getRawY();
                    lastAction = MotionEvent.ACTION_POINTER_DOWN;
                    break;
                default:
                    return false;
            }
            return true;
        }
    };
}
...