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