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