Fixing layouting issues with NonClientDecorView

Also fixing focus issue where the non client decor view
focus bar could aquire the focus.

Bug: 22984173
Bug: 23115816
Change-Id: Id0e6645004404018ea29dd035ea8a15275e12da9
This commit is contained in:
Skuhne
2015-08-11 17:18:58 -07:00
parent cd703b6235
commit f7b882c9c6
3 changed files with 18 additions and 38 deletions

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.Window;
@@ -55,7 +56,7 @@ import com.android.internal.policy.PhoneWindow;
* </ul>
* This will be mitigated once b/22527834 will be addressed.
*/
public class NonClientDecorView extends ViewGroup implements View.OnClickListener {
public class NonClientDecorView extends LinearLayout implements View.OnClickListener {
private final static String TAG = "NonClientDecorView";
// The height of a window which has focus in DIP.
private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
@@ -90,6 +91,7 @@ public class NonClientDecorView extends ViewGroup implements View.OnClickListene
mOwner = owner;
mWindowHasShadow = windowHasShadow;
mShowDecor = showDecor;
updateCaptionVisibility();
if (mWindowHasShadow) {
initializeElevation();
}
@@ -107,6 +109,7 @@ public class NonClientDecorView extends ViewGroup implements View.OnClickListene
**/
public void phoneWindowUpdated(boolean showDecor, boolean windowHasShadow) {
mShowDecor = showDecor;
updateCaptionVisibility();
if (windowHasShadow != mWindowHasShadow) {
mWindowHasShadow = windowHasShadow;
initializeElevation();
@@ -129,49 +132,18 @@ public class NonClientDecorView extends ViewGroup implements View.OnClickListene
super.onWindowFocusChanged(hasWindowFocus);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// The system inset needs only to be applied to the caption. The client area of
// the window will automatically be adjusted by the the DecorView.
WindowInsets insets = getRootWindowInsets();
int systemMargin = insets.getSystemWindowInsetTop();
final int leftPos = getPaddingLeft();
final int rightPos = right - left - getPaddingRight();
final int topPos = getPaddingTop();
final int bottomPos = bottom - top - getPaddingBottom();
// On top we have the caption which has to fill left to right with a fixed height.
final int width = rightPos - leftPos;
final View caption = getChildAt(0);
// If the application changed its SystemUI metrics, we might also have to adapt
// our shadow elevation.
updateElevation();
mAllowUpdateElevation = true;
// Don't show the decor if the window has e.g. entered full screen.
final int captionHeight =
(isFillingScreen() || !mShowDecor) ? 0 : caption.getMeasuredHeight();
caption.layout(leftPos, topPos + systemMargin, leftPos + width,
topPos + systemMargin + captionHeight);
// Note: We should never have more then 1 additional item in here.
if (getChildCount() > 1) {
getChildAt(1).layout(leftPos, topPos + captionHeight, leftPos + width, bottomPos);
}
super.onLayout(changed, left, top, right, bottom);
}
@Override
public void addView(View child, int index, LayoutParams params) {
public void addView(View child, int index, ViewGroup.LayoutParams params) {
// Make sure that we never get more then one client area in our view.
if (index >= 2 || getChildCount() >= 2) {
throw new IllegalStateException("NonClientDecorView can only handle 1 client view");
@@ -189,6 +161,16 @@ public class NonClientDecorView extends ViewGroup implements View.OnClickListene
View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LOW_PROFILE)));
}
/**
* Updates the visibility of the caption.
**/
private void updateCaptionVisibility() {
// Don't show the decor if the window has e.g. entered full screen.
boolean invisible = isFillingScreen() || !mShowDecor;
View caption = getChildAt(0);
caption.setVisibility(invisible ? GONE : VISIBLE);
}
/**
* The elevation gets set for the first time and the framework needs to be informed that
* the surface layer gets created with the shadow size in mind.

View File

@@ -20,8 +20,7 @@
<com.android.internal.widget.NonClientDecorView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_height="match_content"
android:descendantFocusability="beforeDescendants" >
<LinearLayout
android:layout_width="match_parent"

View File

@@ -20,8 +20,7 @@
<com.android.internal.widget.NonClientDecorView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_height="match_content"
android:descendantFocusability="beforeDescendants" >
<LinearLayout
android:layout_width="match_parent"