2012-01-12 27 views
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) 
} 

それは基本的にdragshadowを作成し、ドラッグ操作を開始します。

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ある:scaleDetector.onTouchEvent(event)は、以下になった後

onScale()の実装は、それが呼び出されます。 parentLayoutは、画面上のImageViewの位置とサイズを管理する拡張AbsoluteLayoutです。

私の問題は、スケーリングが機能せず、ドラッグアンドドロップだけです。スケーリングは実行されず、ビューを移動するだけで動作します。私がlinke startDragNDrop()をコメントアウトすると、スケーリングは機能しますが、ビューを移動することは明らかにできません。誰かがイメージビューのものにこれらを組み合わせる方が良いアイデアはありますか?

+0

あなたをしましたthiへの解決策を見つける?私も同様の問題があります。 – Amanni

+0

残念ながら、いいえ。私は最終的にスケーリング機能を落とさなければならなかった。 – Dude

答えて

0

あなたのonScaleBeginメソッドはfalseを返しますか?私が似たようなことをしようとしていたときに、falseを返したonScaleBeginメソッドが作成されました。これはAndroidにスケーリングジェスチャーの残りの部分を無視するように指示します。 AndroidがonScaleとonScaleEndを呼び出すようにするには、onScaleBeginをtrueに戻す必要がありました。 もう1つの問題は、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); 
} 

}

関連する問題