组合拖放和缩放

问题描述 投票:2回答:2

我实现了一个可移动的图像视图,可以用手指四处移动,也可以缩放。我使用拖放框架来移动它(因为我也需要它可拖放),并且我有一个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)
}

基本上创建拖动阴影并开始拖动操作。

onScale()的实现,即在scaleDetector.onTouchEvent(event)之后调用的是以下内容:

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.fparentLayout是扩展的AbsoluteLayout,它管理屏幕上ImageView的位置和大小。

我的问题是缩放功能不起作用,只能拖放。不执行缩放,仅在视图中移动即可。如果我注释掉链接startDragNDrop(),则缩放有效,但在视图周围移动显然无效。有谁有更好的主意将这些结合到imageview中的东西上?

android android-layout android-widget
2个回答
0
投票

您的onScaleBegin方法是否返回false?当我尝试执行类似操作时,Eclipse创建了一个onScaleBegin方法,该方法返回false。这告诉Android忽略其余的缩放手势。为了让Android调用onScale和onScaleEnd,我必须使onScaleBegin返回true。我遇到的另一个问题是,根据Android reference for OnScaleGestureListener,即使onScaleBegin返回true,也可能永远不会调用onScale。因此,我将缩放计算放在onScaleEnd中。这种解决方案对我有用,因为我只想为每个捏或张开手势调整一次缩放比例。


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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.