1 package com.android.launcher3; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Rect; 6 import android.util.AttributeSet; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.FrameLayout; 10 11 public class InsettableFrameLayout extends FrameLayout implements 12 ViewGroup.OnHierarchyChangeListener, Insettable { 13 14 protected Rect mInsets = new Rect(); 15 InsettableFrameLayout(Context context, AttributeSet attrs)16 public InsettableFrameLayout(Context context, AttributeSet attrs) { 17 super(context, attrs); 18 setOnHierarchyChangeListener(this); 19 } 20 setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets)21 public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) { 22 final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 23 24 if (child instanceof Insettable) { 25 ((Insettable) child).setInsets(newInsets); 26 } else if (!lp.ignoreInsets) { 27 lp.topMargin += (newInsets.top - oldInsets.top); 28 lp.leftMargin += (newInsets.left - oldInsets.left); 29 lp.rightMargin += (newInsets.right - oldInsets.right); 30 lp.bottomMargin += (newInsets.bottom - oldInsets.bottom); 31 } 32 child.setLayoutParams(lp); 33 } 34 35 @Override setInsets(Rect insets)36 public void setInsets(Rect insets) { 37 final int n = getChildCount(); 38 for (int i = 0; i < n; i++) { 39 final View child = getChildAt(i); 40 setFrameLayoutChildInsets(child, insets, mInsets); 41 } 42 mInsets.set(insets); 43 } 44 45 @Override generateLayoutParams(AttributeSet attrs)46 public LayoutParams generateLayoutParams(AttributeSet attrs) { 47 return new InsettableFrameLayout.LayoutParams(getContext(), attrs); 48 } 49 50 @Override generateDefaultLayoutParams()51 protected LayoutParams generateDefaultLayoutParams() { 52 return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 53 } 54 55 // Override to allow type-checking of LayoutParams. 56 @Override checkLayoutParams(ViewGroup.LayoutParams p)57 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 58 return p instanceof InsettableFrameLayout.LayoutParams; 59 } 60 61 @Override generateLayoutParams(ViewGroup.LayoutParams p)62 protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 63 return new LayoutParams(p); 64 } 65 66 public static class LayoutParams extends FrameLayout.LayoutParams { 67 boolean ignoreInsets = false; 68 LayoutParams(Context c, AttributeSet attrs)69 public LayoutParams(Context c, AttributeSet attrs) { 70 super(c, attrs); 71 TypedArray a = c.obtainStyledAttributes(attrs, 72 R.styleable.InsettableFrameLayout_Layout); 73 ignoreInsets = a.getBoolean( 74 R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false); 75 a.recycle(); 76 } 77 LayoutParams(int width, int height)78 public LayoutParams(int width, int height) { 79 super(width, height); 80 } 81 LayoutParams(ViewGroup.LayoutParams lp)82 public LayoutParams(ViewGroup.LayoutParams lp) { 83 super(lp); 84 } 85 } 86 87 @Override onChildViewAdded(View parent, View child)88 public void onChildViewAdded(View parent, View child) { 89 setFrameLayoutChildInsets(child, mInsets, new Rect()); 90 } 91 92 @Override onChildViewRemoved(View parent, View child)93 public void onChildViewRemoved(View parent, View child) { 94 } 95 96 } 97