2012-01-12 96 views
2

我已經實現了一個可移動的圖像視圖,我可以用手指移動並縮放。我使用拖放框架來移動它(因爲我也需要拖放),並且我有一個處理縮放的ScaleGestureDetector.SimpleOnScaleGestureListenerMovableImageView擴展了Android的正常ImageView。當用戶觸摸圖像視圖時,方法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並啓動拖動操作。

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.f。而parentLayout是一個擴展的AbsoluteLayout,用於管理屏幕上ImageView的位置和大小。

我的問題是,縮放不起作用,只有拖放。不執行縮放,只能在視圖中移動。如果我註釋掉linke startDragNDrop(),那麼縮放工作,但顯然不是在視圖周圍移動。有沒有人有更好的想法將這些與imageview中的東西結合起來?

+0

你有沒有找到一個解決方案S'我有類似的問題 – Amanni 2014-03-17 10:20:04

+0

不幸的是,沒有。我不得不最終放棄縮放功能。 – Dude 2014-03-17 13:44:31

回答

0

您的onScaleBegin方法返回false?當我試圖做類似的Eclipse時,創建了一個返回false的onScaleBegin方法。這告訴Android忽略縮放手勢的其餘部分。爲了讓Android調用onScale和onScaleEnd,我必須讓onScaleBegin返回true。 我的另一個問題是根據Android reference for OnScaleGestureListener onScale可能永遠不會被調用,即使onScaleBegin返回true。因此,我把我的縮放計算放在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); 
} 

}