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