How to programmatically adjust z order of Views

Jarrod Smith picture Jarrod Smith · Mar 22, 2012 · Viewed 9.6k times · Source

The below code is my attempt to send mMyView to the front or the back of the set of children of mPivotParent so it will be rendered on top or behind the others. Hiding the view will not suffice in my case.

mPivotParent is a FrameLayout.

Looking at mPivotParent.mChildren shows that my code below "works" in that the ordering is being set correctly. Yet it has no impact on the z order. Not only this, but the framerate gets cumulatively slower and slower the more times the repositioning code gets called. There are 4 children total and mPivotParent.mChildrenCount remains at 4 throughout as expected.

I'm targeting API Level 7.

@Override
public boolean onTouchEvent(MotionEvent event) {
    Display display = getWindowManager().getDefaultDisplay();

    float x = event.getRawX();
    float sWidth = (int)display.getWidth();
    float xLerpFromCenter = ((x / sWidth) - .5f) * 2.f;             // [-1, 1]
    mRotateAnimation.mfLerp = xLerpFromCenter;

    if(xLerpFromCenter < -0.2f && mPivotParent.getChildAt(0) != mMyView)
    {
        mPivotParent.removeView(mMyView);
        mPivotParent.addView(mMyView, 0);
        refreshEverything();
    }
    else if(xLerpFromCenter > 0.2f && mPivotParent.getChildAt(0) == mMyView)
    {
        mPivotParent.removeView(mMyView);
        mPivotParent.addView(mMyView, mPivotParent.getChildCount() - 1);
        refreshEverything();
    }

    return super.onTouchEvent(event);
}

private void refreshEverything()
{
    for(int i = 0; i < mPivotParent.getChildCount(); ++i)
    {
        mPivotParent.getChildAt(i).invalidate();
        mPivotParent.getChildAt(i).requestLayout();
    }
    mPivotParent.invalidate();
    mPivotParent.requestLayout();
}

Answer

Jarrod Smith picture Jarrod Smith · Jan 9, 2014

Partial Solution

Here's a somewhat inefficient hack but it works for my purpose, which is to take the top item and send it to the back, keeping all other items in their same order.

private void putFrontAtBack()
{
    for(int i = 0; i < mPivotParent.getChildCount() - 1; ++i)
    {
        mPivotParent.getChildAt(0).bringToFront();
    }
    refreshEverything();
}

Note: This doesn't work in the general case of arbitrary re-ordering.