Stop Android from the layout of all my views

I am currently developing a tablet application that heavily uses the ViewPager widget. I also immediately got a few viewers on the screen.

Now I have the following problem: If one ViewPager scrolls to the next / previous page, it (of course) has to recount its layout and add / remove views. I noticed that requestLayout is called right at the top of the view hierarchy, which invalidates ALL of my views on the tablet screen (which is a lot!). It is very expensive .

Now my question is: is it possible to implement Frame around the ViewPager, which performs the initial layout, and then does not propagate layout requests up the view hierarchy , as I know that after the initial layout, the frame remains the same size and will not change.

I came up with the following frame, but it does not work very well, because it does not work for 100% of the time.

 public class MyFrame extends FrameLayout { // VARIABLE CONTROLLING THE DISPATCH OF THE LAYOUT // REQUEST UP THE VIEW HIERARCHY private boolean doLayout = true; public MyFrame(Context context) { super(context); doLayout = true; } @Override public void requestLayout() { if (doLayout) // DO THE LAYOUT REQUEST UP TO THE TOP super.requestLayout(); else { // JUST MEASURE MYSELF AND MY CHILDREN measure(MeasureSpec.getMode(MeasureSpec.AT_MOST), MeasureSpec.getMode(MeasureSpec.AT_MOST)); layout(getLeft(), getTop(), getRight(), getBottom()); } doLayout = false; } } 

Thanks for any advice!

+8
android android-layout android-viewpager android-widget android-custom-view
source share
2 answers

I know the question is a bit outdated, but my answer may help someone else, since your question and Colin's answer helped me.

I have exactly the same problem as you. And there are two solutions for this. First you need to make sure that your ViewPager has * layout_width * and * layout_height * set to * match_parent *, and this view hierarchy is organized in such a way that Android does not come to the conclusion that it needs to redeploy any parent ViewPager layouts. For example, let's say you have a RelativeLayout with two views of fixed sizes, one below the other and a ViewPager under the second view. In this case, any change in the ViewPager will apply to the parent layout. However, if you place these two types of fixed size and ViewPager in LinearLayout, this does not happen, the layout request will not extend beyond the ViewPager. What's even better, a layout request on one page of the ViewPager will not extend to other pages.

The second solution (actually this is the second part of the solution) is your FrameLayout, but it has changed as follows:

 public class LayoutStopperFrameLayout extends FrameLayout { private boolean doLayout; public LayoutStopperFrameLayout(Context context) { super(context); doLayout = true; } public LayoutStopperFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); doLayout = true; } public LayoutStopperFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); doLayout = true; } public void setPropagateRequestLayout(boolean doLayout) { this.doLayout = doLayout; } @Override public void requestLayout() { if (doLayout) { // DO THE LAYOUT REQUEST UP TO THE TOP super.requestLayout(); } } } 

In my application, I call setPropagateRequestLayout () on the Fragment onStart and onStop methods to enable or disable layout requests.

+4
source share

I would very much like to say that there is a better way, but I do not think there is. If the ViewPager uninterestingly adds / removes views, your layout will be constantly broken, even if it is not. This is a lazy assumption that the content may change (thus, invalid up), and it is difficult for us to implement some of these assumptions.

If you can guarantee that the boundaries of FrameLayout will never change, there is no harm in over-writing requestLayout at all.

0
source share

All Articles