2016-12-21 21 views
0

何らかの理由で何らかの理由で私はこの問題が発生した理由を理解できませんが、imageViewを使用してイメージを実用的にサイズ変更しますが、 onTouchイベントでそれらを再適用するまで変更されます。onActivityResultのimageViewでイメージのサイズを変更して再描画する

このアクティビティの機能は、ギャラリーピッカーをすぐに開き、画像をパンしたりサイズを変更できるimageViewに結果を表示することです。その後、描画キャッシュはビットマップとしてストレージに保存されます。

ImageViewのサイズを実際には正方形に変更して、新しい寸法に合わせて画像のサイズを変更する必要があります。しかし、画面をタップするまでは、常に中央に表示されます。

はここに私のコードの嘆願は私

public class PickPic extends Activity { 

private static final String D = "PickPic"; 
float scaleAmount = 1; 
//this view determines what part of the image will be kept 
ImageView cropView; 
Bitmap b; 
ScaleGestureDetector scaleD; 
//for touch event handling 
float initX,initY; 
//cropview image matrix 
Matrix matC; 
int resultCode; 

float scale; 
//cropview image matrix translation values 
float cropTransX, cropTransY; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_pick_pic); 

    resultCode = getIntent().getIntExtra("result code", MainActivity.PICK_PIC_4_PIC_ONE); 

    scaleD = new ScaleGestureDetector(this, new ScaleListener()); 

    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI); 
    startActivityForResult(intent, 1); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    cropView = (ImageView) findViewById(R.id.editor); 
    cropView.setDrawingCacheEnabled(true); 
    //make crop view square 
    cropView.getLayoutParams().height = cropView.getWidth(); 
    cropView.requestLayout(); 

    if (resultCode == RESULT_OK) { 
     try { 
      b = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData()); 
      cropView.setImageBitmap(b); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 
    setValues(); 
} 

private void setValues() { 
    matC = cropView.getImageMatrix(); 
    //scale crop to fit 
    matC = scale(matC,b.getWidth(),b.getHeight(),cropView.getWidth(),cropView.getWidth()); 
    float[] matCValues = new float[9]; 
    matC.getValues(matCValues); 
    //transformation values to be kept for onTouch methods 
    scale = matCValues[Matrix.MSCALE_X]; 
    cropTransX = matCValues[Matrix.MTRANS_X]; 
    cropTransY = matCValues[Matrix.MTRANS_Y]; 
    cropView.setImageMatrix(matC); 
    cropView.invalidate(); 
    //here the values get set properly but the display doesn't change 
} 

private Matrix scale(Matrix mat, float bwidth, float bheight, float vwidth, float vheight) { 

    float scale; 
    float dx = 0, dy = 0; 

    if (bwidth * vheight > vwidth * bheight) { 
     scale = vheight/bheight; 
     dx = (vwidth - bwidth * scale) * 0.5f; 
    } else { 
     scale = vwidth/bwidth; 
     dy = (vheight - bheight * scale) * 0.5f; 
    } 

    mat.setTranslate(Math.round(dx), Math.round(dy)); 
    mat.preScale(scale, scale); 
    //mat.setScale(scale, scale); 
    //mat.postTranslate(Math.round(dx), Math.round(dy)); 

    return mat; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    scaleD.onTouchEvent(event); 

    switch (MotionEventCompat.getActionMasked(event)){ 
     case (MotionEvent.ACTION_DOWN): 
      initX = event.getX(); 
      initY = event.getY(); 
      return true; 
     case (MotionEvent.ACTION_MOVE): 
      //this is where the display gets updated 
      matC.setTranslate(cropTransX + event.getX() - initX, cropTransY + event.getY() - initY); 
      matC.preScale(scale*scaleAmount, scale*scaleAmount); 
      cropView.setImageMatrix(matC); 
      cropView.invalidate(); 
      matB.setTranslate(backTransX + event.getX() - initX, backTransY + event.getY() - initY); 
      matB.preScale(scale*scaleAmount, scale*scaleAmount); 
      return true; 
     case (MotionEvent.ACTION_UP): 
      //commit transformations 
      cropTransX += event.getX() - initX; 
      cropTransY += event.getY() - initY; 

      backTransX += event.getX() - initX; 
      backTransY += event.getY() - initY; 
      return true; 
     default: 
      return super.onTouchEvent(event); 
    } 
} 

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     scaleAmount *= detector.getScaleFactor(); 
     return true; 
    } 
} 
} 

答えて

0

は、以下のようなonActivityResultでいくつかの遅延と呼ばれるsetValues()メソッドを()してください助けます。

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
super.onActivityResult(requestCode, resultCode, data); 

cropView = (ImageView) findViewById(R.id.editor); 
cropView.setDrawingCacheEnabled(true); 
//make crop view square 
cropView.getLayoutParams().height = cropView.getWidth(); 
cropView.requestLayout(); 

if (resultCode == RESULT_OK) { 
    try { 
     b = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData()); 
     cropView.setImageBitmap(b); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       setValues(); 
      } 
     },1500); 

}

働いていないなら、私は結果を知っています。

+0

これは動作しますが、遅延があります。また、私はsetValues()を呼び出す場合、動作するようです。 onWindowFocusChangedメソッドで設定します。あなたはなぜそれがメインのUIスレッドで動作しないか考えていますか? – thefatb0b

+0

メインUIスレッドにあります。ビットマップに変換するのには時間がかかります。だからこそ遅延が必要です。 – MdFazlaRabbiOpu

関連する問題