ozodrukh / CircularReveal

Lollipop ViewAnimationUtils.createCircularReveal for everyone 4.0+
MIT License
2.43k stars 391 forks source link

Why drawChild #7

Closed nschwermann closed 9 years ago

nschwermann commented 9 years ago

I was reviewing the code for your RevealFrameLayout, your solution to clip the canvas is pretty clever! However, why did you override drawChild?

You should override draw instead. With your current implementation you make the clip path calculation for each view in the layout, however it could be done all at once in draw.

Also I believe your current implementation wouldn't clip the background drawable but I haven't tested that.

ozodrukh commented 9 years ago

Thanks for question,

Do you know how does ViewGroup draws children? (link to reference where does it draw child)


    ViewGroup#dispatchDraw() ->
       ViewGroup#drawChild(Canvas, View, long) ->
            View#draw(Canvas) ->
             // drawing view & his background 
                 View#drawBackground(Canvas) // Step 1, draw the background, if needed
                 View#dispatchDraw(Canvas)
                 View#onDraw() // step 3 draw content
                 View#dispatchDraw(Canvas) // step 4 draw the children

so if we modify passed in ViewGroup#drawChild(Canvas, View, long) Canvas we can modify how does view will be drawn, because of View#onDraw(Canvas) method cannot clip view self(because called last) & background(already drawn)

My apologizes for my English level, if you don't understand something, let me know, i will do my best to try explain better.

ozodrukh commented 9 years ago

if you understand, please close issue :)

nschwermann commented 9 years ago

onDraw does not work but draw seems to be working for me, I've been playing around with it and I have clipping working like this.

@Override
public void draw(Canvas canvas) {
    if(!mClipOutlines){
        super.draw(canvas);
        return;
    }
    final int state = canvas.save();
    mRevealPath.reset();
    mRevealPath.addCircle(mCenterX, mCenterY, mRadius, Path.Direction.CW);
    canvas.clipPath(mRevealPath);
    super.draw(canvas);
    canvas.restoreToCount(state);
}
ozodrukh commented 9 years ago

Why do you try to modify View#draw(Canvas) ? in this case we must implement it (reveal clipping) to all views :) i found easier way

nschwermann commented 9 years ago

Oh I see, you only apply it to your target view. I guess my thoughts were it would be easier to not have to worry about a target but just treat it like a regular FrameLayout. But I understand your reasoning here as well. Thanks.