2012-09-01 29 views
7

मेरे एंड्रॉइड ऐप में, मेरे पास एक फसल छवि है। तो, मैं अपने फसल बॉक्स के रूप में एक कस्टम दृश्य प्रोग्रामिंग। मैं फसल बॉक्स ले जा सकता हूं। लेकिन मेरी समस्या यह है कि मैं फसल बॉक्स की सीमा को कैसे खींच सकता हूं और इसकी चौड़ाई और ऊंचाई बदल सकता हूं। मैं यह कैसे कर सकता हूं?एंड्रॉइड में कस्टम व्यू चौड़ाई और ऊंचाई बदलें

ATTR कक्षा:

public class Attr { 

    public static final float CROP_BOX_START_X = 5; 
    public static final float CROP_BOX_START_Y = 5; 
    public static final float CROP_BOX_END_X = 305; 
    public static final float CROP_BOX_END_Y = 105; 

} 

CropBox कक्षा:

public class CropBox extends View { 

    private Paint paint = new Paint(); 


    public CropBox(Context context) { 
     super(context); 
    } 

    public CropBox(Context context, AttributeSet attributeSet) { 
     super(context, attributeSet); 
    } 


    @Override 
    public void onDraw(Canvas canvas) { 
     float[][] circleXY = { 
      {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y}, 
      {(Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X)/2, Attr.CROP_BOX_START_Y}, 
      {Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y}, 
      {Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y}, 
      {(Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X)/2, Attr.CROP_BOX_END_Y}, 
      {Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y}, 
      {Attr.CROP_BOX_START_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y)/2}, 
      {Attr.CROP_BOX_END_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y)/2} 
     }; 
     float[][] lineXY = { 
      {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y}, 
      {Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y}, 
      {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y}, 
      {Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y} 
     }; 

     paint.setColor(Color.CYAN); 
     paint.setStrokeWidth(1); 

     for(int i = 0 ; i < circleXY.length ; i++) 
      canvas.drawCircle(circleXY[i][0], circleXY[i][1], 5, paint); 

     paint.setStrokeWidth(2); 

     for(int i = 0 ; i < lineXY.length ; i++) 
      canvas.drawLine(lineXY[i][0], lineXY[i][2], lineXY[i][2], lineXY[i][3], paint); 
    } 

} 

CropTestActivity कक्षा:

public class CropTestActivity extends Activity { 

    private ImageView imageView; 
    private CropBox cropBox; 
    private RelativeLayout relativeLayout; 
    private RelativeLayout.LayoutParams layoutParams; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.crop_test_layout); 
     imageView = (ImageView)findViewById(R.id.android_image); 
     cropBox = new CropBox(this); 
     relativeLayout = (RelativeLayout)findViewById(R.id.crop_test_layout); 
     layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT); 
     imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
      public void onGlobalLayout() { 
       imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       layoutParams.leftMargin = imageView.getWidth()/2 - (int)((Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X)/2) + imageView.getLeft(); 
       layoutParams.topMargin = imageView.getHeight()/2 - (int)((Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y)/2) + imageView.getTop(); 
      } 
     }); 
     relativeLayout.addView(cropBox, layoutParams); 
     cropBox.setOnTouchListener(new Crop(imageView)); 
    } 

} 

फसल कक्षा:

public class Crop implements OnTouchListener { 

    private static final int NONE = 0; 
    private static final int BOX_DRAG = 1; 
    private static final int BORDER_DRAG = 2; 

    private int mode = NONE; 

    private float cropBoxStartX = Attr.CROP_BOX_START_X; 
    private float cropBoxStartY = Attr.CROP_BOX_START_Y; 
    private float cropBoxEndX = Attr.CROP_BOX_END_X; 
    private float cropBoxEndY = Attr.CROP_BOX_END_Y; 

    private ImageView imageView; 

    private PointF start = new PointF(); 


    public Crop(ImageView imageView) { 
     this.imageView = imageView; 
    } 


    public boolean onTouch(View view, MotionEvent event) { 
     RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)view.getLayoutParams(); 

     switch(event.getAction() & MotionEvent.ACTION_MASK) { 

      case MotionEvent.ACTION_DOWN: 
       start.set(event.getX(), event.getY()); 
       if(event.getX() > cropBoxStartX && event.getX() < cropBoxEndX && event.getY() > cropBoxStartY && event.getY() < cropBoxEndY) 
        mode = BOX_DRAG; 
       else if(event.getX() == cropBoxStartX || event.getX() == cropBoxEndX || event.getY() == cropBoxStartY || event.getY() == cropBoxEndY) 
        mode = BORDER_DRAG; 
       else 
        mode = NONE; 
       break; 

      case MotionEvent.ACTION_UP: 
       mode = NONE; 
       break; 

      case MotionEvent.ACTION_MOVE: 
       if(mode == BOX_DRAG) { 
        layoutParams.leftMargin = (int)event.getX() - (int)start.x + view.getLeft(); 
        layoutParams.topMargin = (int)event.getY() - (int)start.y + view.getTop(); 
        while(layoutParams.topMargin + 5 < imageView.getTop()) 
         layoutParams.topMargin++; 
        while(layoutParams.leftMargin + (cropBoxEndX - cropBoxStartX + 5) > imageView.getRight()) 
         layoutParams.leftMargin--; 
        while(layoutParams.topMargin + (cropBoxEndY - cropBoxStartY + 5) > imageView.getBottom()) 
         layoutParams.topMargin--; 
        while(layoutParams.leftMargin + 5 < imageView.getLeft()) 
         layoutParams.leftMargin++; 
       } 
       else if(mode == BORDER_DRAG) { 
       } 
       break; 
     } 
     view.setLayoutParams(layoutParams); 
     return true; 
    } 

} 

लेआउट एक्सएमएल:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/crop_test_layout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <ImageView 
     android:id="@+id/android_image" 
     android:src="@drawable/android" 
     android:layout_width="fill_parent" 
     android:layout_height="300dp" 
     android:layout_marginTop="10dp" 
     android:layout_marginRight="10dp" 
     android:layout_marginBottom="10dp" 
     android:layout_marginLeft="10dp" 
     android:layout_gravity="center" 
     android:scaleType="fitXY" 
     android:contentDescription="@string/android_image_description" > 
    </ImageView> 

</RelativeLayout> 

आकार से पहले:

enter image description here

आकार के बाद:

enter image description here

आपकी मदद के लिए धन्यवाद।

+0

आपने अपने गुणों को 'अंतिम' क्यों घोषित किया। यदि आप उन्हें बदलना चाहते हैं, तो क्या आपको अंतिम नहीं घोषित करना चाहिए? –

+0

हाँ, आप सही हैं। मुझे उन्हें अंतिम नहीं घोषित करना होगा। लेकिन मुझे नहीं पता कि मैं उनका आकार कैसे बदल सकता हूं। –

उत्तर

2

के बाद, समाधान है

गतिविधि से संशोधित onCreate

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.crop_test_layout); 
    imageView = (ImageView)findViewById(R.id.android_image); 
    cropBox = new CropBox(this, imageView); 
    relativeLayout = (RelativeLayout)findViewById(R.id.crop_test_layout); 
    relativeLayout.addView(cropBox); 
} 

संशोधित CropBox वर्ग:

public class CropBox extends View { 

    private static final int CROP_BOX_START_X = 5; 
    private static final int CROP_BOX_START_Y = 5; 
    private static final int CROP_BOX_END_X = 305; 
    private static final int CROP_BOX_END_Y = 105; 

    private static final int DRAG_SQUARE = 75; 

    public ImageView mImageView; 
    boolean mIsFirstClick = false; 

    private Paint paint = new Paint(); 
    private Rect mRect; 

    public CropBox(Context context, ImageView aBaseView) { 
     super(context); 
     mImageView = aBaseView; 
     mRect = new Rect(CROP_BOX_START_X, CROP_BOX_START_Y, CROP_BOX_END_X, CROP_BOX_END_Y); 
     setOnTouchListener(new Crop()); 
    } 

    public CropBox(Context context, AttributeSet attributeSet) { 
     super(context, attributeSet); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 

     paint.setStrokeWidth(2); 

     paint.setColor(Color.CYAN); 
     paint.setStyle(Paint.Style.STROKE); 

     canvas.drawRect(mRect, paint); 

     canvas.drawLine(mRect.right-DRAG_SQUARE, mRect.bottom-DRAG_SQUARE, 
       mRect.right, mRect.bottom-DRAG_SQUARE, paint); 

     canvas.drawLine(mRect.right-DRAG_SQUARE, mRect.bottom-DRAG_SQUARE, 
       mRect.right-DRAG_SQUARE, mRect.bottom, paint); 
    } 

    class Crop implements OnTouchListener { 

     private static final int NONE = 0; 
     private static final int BOX_DRAG = 1; 
     private static final int BORDER_DRAG = 2; 

     private int mode = NONE; 

     private PointF start = new PointF(); 

     public boolean onTouch(View view, MotionEvent event) { 
      RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)view.getLayoutParams(); 

      switch(event.getAction() & MotionEvent.ACTION_MASK) { 

       case MotionEvent.ACTION_DOWN: 
        start.set(event.getX(), event.getY()); 

        if((event.getX() <= mRect.right && event.getX() >=(mRect.right - DRAG_SQUARE)) 
          && (event.getY() >= mRect.top && event.getY() >=(mRect.bottom - DRAG_SQUARE))){ 
         mode = BORDER_DRAG; 
         mIsFirstClick = false; 
        } 
        else if(mRect.contains((int)event.getX(), (int)event.getY())) { 
         mode = BOX_DRAG; 
         if (mIsFirstClick){ 
          mRect = new Rect(CROP_BOX_START_X, CROP_BOX_START_Y, 
            CROP_BOX_END_X, CROP_BOX_END_Y); 
          mIsFirstClick = false; 
         } else { 
          mIsFirstClick = true; 
         } 
        } 
        else{ 
         mode = NONE; 
         mIsFirstClick = true; 
        } 
        break; 

       case MotionEvent.ACTION_UP: 
        mode = NONE; 
        break; 

       case MotionEvent.ACTION_MOVE: 
        mIsFirstClick = false; 
        if(mode == BOX_DRAG) { 
         layoutParams.leftMargin = (int)event.getX() - (int)start.x + view.getLeft(); 
         layoutParams.topMargin = (int)event.getY() - (int)start.y + view.getTop(); 
        } 
        else if(mode == BORDER_DRAG) { 
         if (event.getX() > view.getLeft() && event.getY() > view.getTop()){ 
          mRect.right = (int) event.getX(); 
          mRect.bottom = (int) event.getY(); 
         } 
        } 
        while(layoutParams.topMargin + 5 < mImageView.getTop()) 
         layoutParams.topMargin++; 
        while(layoutParams.leftMargin + mRect.right > mImageView.getRight()) 
         layoutParams.leftMargin--; 
        while(layoutParams.topMargin + mRect.bottom > mImageView.getBottom()) 
         layoutParams.topMargin--; 
        while(layoutParams.leftMargin + 5 < mImageView.getLeft()) 
         layoutParams.leftMargin++; 
        break; 
      } 
      view.setLayoutParams(layoutParams); 
      invalidate(); 
      return true; 
     } 
    } 
} 

कुछ बिंदुओं को मैं उल्लेख करना चाहते हैं।

  • मर्ज किए गए ATTR और फसल CropBox
  • लाइनों से एक आयत बनाने की कोई ज़रूरत नहीं है। आप Rect का उपयोग कर सकते हैं।
  • कभी ड्रा विधि
  • एक फीचर जोड़ा गया में एक सरणी/वस्तु प्रारंभ: अगर डबल आयत को छुआ यह imageView में रेक्ट प्रतिबंधित करने के बारे मूल स्थिति में
  • कुछ hitches
  • हो सकती है देता है। मुझे यकीन है कि आप उन ... :)

अन्य इस से ठीक कर सकते हैं वहाँ कैनवास Image in Canvas with touch events की स्केलिंग का उपयोग कर Cropbox के बजाय उस वर्ग का उपयोग करें और यह कोशिश एक और दिलचस्प तरीका है हूँ।

उम्मीद है कि यह मदद करता है ..

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद: डी –

+0

चलती सीमाएं वास्तव में महान काम करती हैं, लेकिन मैं छवि को कैसे फसल कर सकता हूं? मुझे इसे भंडारण में सहेजने की ज़रूरत है। – Ragaisis