Yalantis / uCrop

Image Cropping Library for Android
https://yalantis.com/blog/introducing-ucrop-our-own-image-cropping-library-for-android/
11.86k stars 2.16k forks source link

How to get the RectF of the crop bounds when activity first start up? #82

Closed vxhviet closed 8 years ago

vxhviet commented 8 years ago

Dear @shliama,

I' currently trying to attach my own rotating wheel below the Crop Bounds. I've managed to do it in the onClick event of the cropAspectRatioView like this:

private void setupAspectRatioWidget() {

        // Set the colors before the default item is selected
        ...

        for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
            cropAspectRatioView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    mGestureCropImageView.setTargetAspectRatio(
                            ((AspectRatioTextView) ((ViewGroup) v).getChildAt(0)).getAspectRatio(v.isSelected()));

                    mGestureCropImageView.setImageToWrapCropBounds();
                    if (!v.isSelected()) {
                        for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
                            cropAspectRatioView.setSelected(cropAspectRatioView == v);
                        }
                    }

                    //TODO: update protractor position here
                   mProtractorWheelView.setY((float)mUCropView.getHeight()/2 + mRectF.height()/2);
                }
            });
        }
    }

the mRectF is the private mCropViewRect retrieved from OverlayView using reflection. My wheel view update nicely when the ratio get changed.

However the problem is when I try to position my wheel view below the crop bound when the activity first start up, the wheel is place at wrong position. If I understand your code correctly, you only call mViewOverlay.postInvalidate();:

public UCropView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        ...

        mGestureCropImageView.setCropBoundsChangeListener(new CropImageView.CropBoundsChangeListener() {
            @Override
            public void onCropBoundsChangedRotate(float cropRatio) {
                if (mViewOverlay != null) {
                    mViewOverlay.setTargetAspectRatio(cropRatio);
                    mViewOverlay.postInvalidate(); 
                }
            }
        });

        ...
    }

when there's a ratio change. And as such when the activity first start, when I try to get mCropViewRect, it still retain the old value. Is there anyway to get the updated mCropViewRect value when everything are fully initialized?

Thank you so much for your time.

vxhviet commented 8 years ago

I would like to add, I solve this by addOnGlobalLayoutListener() to the mOverlayView object in initiateRootViews(). Something like this:

//init position
        mOverlayView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mRectF = getOverlayViewRectF();
                //do your thing
            }
        });

Hope this help someone,

shliama commented 8 years ago

Yes, I read #81 and this issues, and I'll try to provide more methods and callbacks in the next update so you won't need to use reflection etc.

vxhviet commented 8 years ago

Awesome, thanks you for your time.

shliama commented 8 years ago

Please try version 1.5.0. I've added getter for mCropViewRect in OverlayView, and also revised logic (because now uCrop supports freestyle crop) so OverlayViewChangeListener#onCropRectUpdated(RectF cropRect) will always update you with the current crop rectangle.

wzgl5533 commented 6 years ago

How can I get current RectF of the cropView?or current instace of OverlayView?