如何在同一视图上实现Touch监听器和捏缩放



我想实现触摸监听器来移动视图,并实现捏缩放来缩放视图,但当我用手指触摸视图进行捏缩放时,只有触摸监听器才能工作。我无法正确处理缩放请帮帮我,因为我不知道如何实现这一点。我什么都试过了,但解决不了这个问题。

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;
}
};
}
}

尝试这样更新代码。

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;
}
};
}

最新更新