【问题标题】:Combine Drag and Drop and Scaling结合拖放和缩放
【发布时间】:2012-01-12 16:32:53
【问题描述】:

我已经实现了一个可移动的图像视图,我可以用手指四处移动并进行缩放。我使用拖放框架来移动它(因为我还需要它可拖放),并且我有一个处理缩放的ScaleGestureDetector.SimpleOnScaleGestureListenerMovableImageView 扩展了普通的 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)
}

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

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在屏幕上的位置和大小。

我的问题是缩放不起作用,只有拖放。不执行缩放,仅在视图中移动。如果我注释掉链接startDragNDrop(),则缩放有效,但在视图中移动显然不行。有没有人更好的想法将这些与图像视图中的东西结合起来?

【问题讨论】:

  • 您找到解决方案了吗?我也有类似的问题
  • 不幸的是,没有。我最终不得不放弃缩放功能。

标签: android android-layout android-widget


【解决方案1】:

对于您所寻求的,我取得了类似的结果。也许那个 sn-p 会帮助你:

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();

调整大小动画():

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2013-02-04
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 1970-01-01
      • 2015-09-24
      • 2019-11-13
      相关资源
      最近更新 更多