android - Invalidate() doesn't actually redraw children -
so, have pretty weird setup, , i'm getting weird visual bugs out of it. basically, have 2 views in relative layout: first imageview background image; second same background image blurred give kind of behind-frosted-glass effect:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/profile_holder" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- background --> <imageview android:id="@+id/backgroundimage" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignparentleft="true" android:layout_alignparenttop="true" android:layout_marginleft="0dp" android:layout_margintop="0dp" android:scaletype="centercrop" android:src="@drawable/default_logo" /> <!-- blurry background --> <com.custom.maskedblurredbackgroundview_ android:id="@+id/blurred_background" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignparentleft="true" android:layout_alignparenttop="true" android:layout_marginleft="0dp" android:layout_margintop="0dp" /> <scrollview android:id="@+id/scrolly" android:layout_width="match_parent" android:layout_height="match_parent" android:fillviewport="true" android:layout_alignparentleft="true" android:layout_alignparenttop="true" > <com.custom.halvedlinearlayout_ android:paddingtop="100dp" android:id="@+id/profileholder" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <button android:id="@+id/profilebuttontracks" style="@style/profilebuttons" android:drawableleft="@drawable/ic_profile_menu_music" android:text="@string/profile_button_tracks" /> ...
the blurred background should behind halvedlinearlayout_ view, scrolls up, need blurred background mask above halvedlinearlayout_ non-blurry background shows through:
scrolly = ((scrollview) rootview.findviewbyid(r.id.scrolly)); scrolly.setonscrolllistener(new scrollview.onscrolllistener() { private boolean hasscrolled = false; @override public void onscrollchanged(int l, int t, int oldl, int oldt) { if (!hasscrolled) { hasscrolled = true; logger.action(logger.action.bioview, band); } positionmask(); } }); ... protected void positionmask() { if (blurredbackground == null) return; logger.d(tag, "positionmask() " + rootview.getid()); //blurredbackground.setmaskbottom(blurredbackground.getheight() - profileholder.getpaddingtop() - scrolly); blurredbackground.setmaskbottom(profileholder.gettop() + profileholder.getpaddingtop() - scrolly.getscrolly()); //blurredbackground.invalidate(); //profileholder.invalidate(); rootview.postinvalidate(); }
now, problem works should, except huge glaring fact when scroll scrollview, blurredbackground draws on halvedlinearlayout_, obliterating buttons in it. (but halfway, sometimes. fine, half button drawn on , other half preserved... kinds of weird glitches.)
i started debugging, , noticed interesting: calling invalidate() on rootview doesn't invalidate() children. overrode invalidate , draw functions logging stuff:
public class maskedblurredbackgroundview extends blurredbackgroundview { /*** * sets mask cover above given y coordinate * @param t y coordinate in pixels */ public void setmaskbottom(int y) { maskbottom = y; } private void clipcanvas(canvas canvas) { logger.d(tag, "dispatchdraw clipping: " + maskbottom + ", " + getwidth() + "," + getheight()); canvas.cliprect(0, maskbottom, getwidth(), getheight(), region.op.replace); } @override protected void dispatchdraw(canvas canvas) { canvas.save(); clipcanvas(canvas); super.dispatchdraw(canvas); canvas.restore(); } @override protected boolean drawchild(canvas canvas, view child, long drawingtime) { logger.d(tag, "drawchild: " + child + getwidth() + "," + getheight()); return super.drawchild(canvas, child, drawingtime); } @override public void invalidate() { logger.d(tag, "invalidate: " + getwidth() + "," + getheight()); super.invalidate(); }
and when @ log, rootview.invalidate() firing when scroll, children never redraw:
07-23 12:36:49.328: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.348: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.348: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.368: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.368: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.378: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.398: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.418: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.448: d/banddetailfrag(12982): positionmask() 2131165298 07-23 12:36:49.478: d/banddetailfrag(12982): positionmask() 2131165298
how force children redraw, in correct order? right i'm guessing draw out of order , that's why blurry background drawing on top of else.
here's screenshot of glitch:
ok, figured out how rid of glitching, @ least: had change "region.op.replace" "region.op.intersect" , works!
invalidate() still doesn't redraw children, guess i'll let slide it's working.
Comments
Post a Comment