我已经实现了一个可移动的图像视图,我可以用手指和缩放来移动。我使用拖放框架移动它(因为我还需要它拖放),我有一个ScaleGestureDetector.SimpleOnScaleGestureListener
来处理缩放。 MovableImageView
扩展了普通ImageView
表单Android。当用户触摸图像视图时,调用方法onTouchEvent(MotionEvent event)。此方法如下所示:
public boolean onTouchEvent(MotionEvent event)
{
scaleDetector.onTouchEvent(event);
startDragNDrop();
return true;
}
startDragNDrop()
看起来像这样:
private void startDragNDrop() {
// Create a new ClipData.
// This is done in two steps to provide clarity. The convenience method
// ClipData.newPlainText() can create a plain text ClipData in one step.
// Create a new ClipData.Item from the ImageView object's tag
ClipData.Item item = new ClipData.Item(mediaItem.getMediaIdentifier());
// Create a new ClipData using the tag as a label, the plain text MIME type, and
// the already-created item. This will create a new ClipDescription object within the
// ClipData, and set its MIME type entry to "text/plain"
String[] mimeType = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData dragData = new ClipData((CharSequence) this.getTag(),mimeType,item);
// Instantiates the drag shadow builder.
DragShadowBuilder myShadow = new ZPACDragShadowBuilder(this);
actualyDraggedView = this;
// Starts the drag
this.startDrag(dragData, // the data to be dragged
myShadow, // the drag shadow builder
null, // no need to use local data
0); // flags (not currently used, set to 0)
}
它基本上创建了dragshadow并开始拖动操作。
在scaleDetector.onTouchEvent(event)
之后调用的onScale()的实现如下:
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = MovableImageView.this.SCALE_FACTOR;
scaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 2.0f));
int width = (int) (MovableImageView.this.getWidth()*scaleFactor);
int height = (int) (MovableImageView.this.getHeight()*scaleFactor);
Log.e("MovableImageView", "Scale Gesture Captured. Scaling Factor " + scaleFactor + " old width " + MovableImageView.this.getWidth() + ", new width " + width);
AbsoluteLayout.LayoutParams layoutParams = new AbsoluteLayout.LayoutParams(width, height, MovableImageView.this.getLeft(), MovableImageView.this.getTop());
parentLayout.updateViewLayout(MovableImageView.this, layoutParams);
invalidate();
return true;
}
字段SCALE_FACTOR
是一个浮点数,值为1.f
。 parentLayout
是一个扩展的AbsoluteLayout,用于管理屏幕上ImageView的位置和大小。
我的问题是缩放不起作用,只有拖放。不执行缩放,仅在视图周围移动。如果我注释掉了linke startDragNDrop()
,那么缩放就可以了,但显然不是在视图中移动。有没有人有更好的想法将这些与图像视图中的东西结合起来?
答案 0 :(得分:0)
你的onScaleBegin方法是否返回false?当我尝试做类似的事情时,Eclipse创建了一个返回false的onScaleBegin方法。这告诉Android忽略其余的缩放手势。为了让Android调用onScale和onScaleEnd,我不得不让onScaleBegin返回true。 我遇到的另一个问题是,即使onScaleBegin返回true,根据Android reference for OnScaleGestureListener onScale也可能永远不会被调用。因此,我将缩放计算放在onScaleEnd中。这个解决方案对我有用,因为我只想为每个捏合或展开手势调整一次缩放。
答案 1 :(得分:0)
我为你所追求的目标取得了类似的成果。也许该片段会帮助你:
在onClickListener()中:
AnimatorSet scale = resizeAnimation(v, 1.2f);
scale.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
v.startDrag(dragData, // the data to be dragged
new MyDragShadowBuilder(v), // the drag shadow builder
v,
0 // flags (not currently used, set to 0)
);
}
});
scale.start();
ResizeAnimation():
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private AnimatorSet resizeAnimation(View view, float scale) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", scale);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", scale);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(scaleX, scaleY);
animSetXY.setDuration(200);
animSetXY.setInterpolator(new AccelerateDecelerateInterpolator());
return animSetXY;
}
MyDragShadowBuilder:
private static class MyDragShadowBuilder extends View.DragShadowBuilder {
// The drag shadow image, defined as a drawable thing
private static Drawable shadow;
int width, height;
public MyDragShadowBuilder(View v) {
width = (int) (v.getWidth() * 1.2f);
height = (int) (v.getHeight() * 1.2f);
v.setDrawingCacheEnabled(true);
v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW); //Quality of the snapshot
Bitmap snapshot;
try {
snapshot = Bitmap.createBitmap(v.getDrawingCache()); // You can tell how to crop the snapshot and whatever in this method
shadow = new BitmapDrawable(snapshot);
} finally {
v.setDrawingCacheEnabled(false);
}
v.setDrawingCacheEnabled(false);
}
@Override
public void onProvideShadowMetrics (Point size, Point touch){
int halfWidth = width /2, halfHeight = height /2;
shadow.setBounds(0, 0, width, height);
size.set(width, height);
touch.set(halfWidth, halfHeight);
}
@Override
public void onDrawShadow(Canvas canvas) {
shadow.draw(canvas);
}
}