1df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska/*
2df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * Copyright (C) 2016 The Android Open Source Project
3df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska *
4df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * Licensed under the Apache License, Version 2.0 (the "License");
5df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * you may not use this file except in compliance with the License.
6df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * You may obtain a copy of the License at
7df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska *
8df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska *      http://www.apache.org/licenses/LICENSE-2.0
9df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska *
10df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * Unless required by applicable law or agreed to in writing, software
11df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * distributed under the License is distributed on an "AS IS" BASIS,
12df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * See the License for the specific language governing permissions and
14df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * limitations under the License.
15df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska */
169b028c55b13889bf75b5dd43b5b0f4051834ae1dAga Madurskapackage android.support.wear.widget;
17df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
18df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.content.Context;
19df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.content.res.Resources;
20df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.content.res.TypedArray;
21df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.graphics.Rect;
22df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.graphics.drawable.Drawable;
23df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.os.Build;
24df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.support.annotation.IntDef;
25df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.support.annotation.NonNull;
26df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.support.annotation.Nullable;
2721061fa807a55ee22f733683cc3c33c87c484f69Aga Madurskaimport android.support.annotation.RestrictTo;
28df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.support.annotation.StyleRes;
29df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.support.annotation.UiThread;
309b028c55b13889bf75b5dd43b5b0f4051834ae1dAga Madurskaimport android.support.wear.R;
31df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.util.AttributeSet;
32df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.view.Gravity;
33df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.view.View;
34df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.view.ViewGroup;
35df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.view.WindowInsets;
36df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport android.widget.FrameLayout;
37df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
38df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport java.lang.annotation.Retention;
39df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskaimport java.lang.annotation.RetentionPolicy;
40df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
41df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska/**
42df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * BoxInsetLayout is a screen shape-aware ViewGroup that can box its children in the center
43df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * square of a round screen by using the {@code boxedEdges} attribute. The values for this attribute
44df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * specify the child's edges to be boxed in: {@code left|top|right|bottom} or {@code all}. The
45df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska * {@code boxedEdges} attribute is ignored on a device with a rectangular screen.
46df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska */
47df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska@UiThread
48df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurskapublic class BoxInsetLayout extends ViewGroup {
49df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
50df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private static final float FACTOR = 0.146467f; //(1 - sqrt(2)/2)/2
51df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.START;
52df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
53df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private final int mScreenHeight;
54df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private final int mScreenWidth;
55df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
56df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private boolean mIsRound;
57df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private Rect mForegroundPadding;
58df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private Rect mInsets;
59df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private Drawable mForegroundDrawable;
60df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
61df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    /**
62df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * Simple constructor to use when creating a view from code.
63df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *
64df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param context The {@link Context} the view is running in, through which it can access
65d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska     *                the current theme, resources, etc.
66df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     */
67df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public BoxInsetLayout(@NonNull Context context) {
68df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        this(context, null);
69df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
70df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
71df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    /**
72df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * Constructor that is called when inflating a view from XML. This is called when a view is
73df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * being constructed from an XML file, supplying attributes that were specified in the XML
74d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska     * file. This version uses a default style of 0, so the only attribute values applied are those
75d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska     * in the Context's Theme and the given AttributeSet.
76df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * <p>
77df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * <p>
78df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * The method onFinishInflate() will be called after all children have been added.
79df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *
80df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param context The {@link Context} the view is running in, through which it can access
81d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska     *                the current theme, resources, etc.
82df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param attrs   The attributes of the XML tag that is inflating the view.
83df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     */
84df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public BoxInsetLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
85df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        this(context, attrs, 0);
86df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
87df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
88df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    /**
89df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * Perform inflation from XML and apply a class-specific base style from a theme attribute.
90df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * This constructor allows subclasses to use their own base style when they are inflating.
91df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *
92df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param context  The {@link Context} the view is running in, through which it can
93d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska     *                 access the current theme, resources, etc.
94df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param attrs    The attributes of the XML tag that is inflating the view.
95df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @param defStyle An attribute in the current theme that contains a reference to a style
96df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *                 resource that supplies default values for the view. Can be 0 to not look for
97df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *                 defaults.
98df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     */
99df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public BoxInsetLayout(@NonNull Context context, @Nullable AttributeSet attrs, @StyleRes int
100df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            defStyle) {
101df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        super(context, attrs, defStyle);
102df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // make sure we have a foreground padding object
103df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mForegroundPadding == null) {
104df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mForegroundPadding = new Rect();
105df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
106df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mInsets == null) {
107df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mInsets = new Rect();
108df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
109df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        mScreenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
110df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        mScreenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
111df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
112df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
113df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
114df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
115df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        insets = super.onApplyWindowInsets(insets);
116df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
117df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            final boolean round = insets.isRound();
118df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (round != mIsRound) {
119df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                mIsRound = round;
120df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                requestLayout();
121df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
122df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
123df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
124df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
125df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return insets;
126df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
127df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
128df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
129df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public void setForeground(Drawable drawable) {
130df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        super.setForeground(drawable);
131df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        mForegroundDrawable = drawable;
132df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mForegroundPadding == null) {
133df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mForegroundPadding = new Rect();
134df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
135df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mForegroundDrawable != null) {
136df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            drawable.getPadding(mForegroundPadding);
137df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
138df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
139df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
140df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
141df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public LayoutParams generateLayoutParams(AttributeSet attrs) {
142df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return new BoxInsetLayout.LayoutParams(getContext(), attrs);
143df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
144df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
145df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
146df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    protected void onAttachedToWindow() {
147df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        super.onAttachedToWindow();
148df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
149df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            requestApplyInsets();
150df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        } else {
151df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mIsRound = getResources().getConfiguration().isScreenRound();
152df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            WindowInsets insets = getRootWindowInsets();
153df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            mInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
154df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
155df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
156df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
157df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
158df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
159df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
160df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int count = getChildCount();
161df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // find max size
162df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int maxWidth = 0;
163df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int maxHeight = 0;
164df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int childState = 0;
165df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        for (int i = 0; i < count; i++) {
166df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            final View child = getChildAt(i);
167df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (child.getVisibility() != GONE) {
168df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                LayoutParams lp = (BoxInsetLayout.LayoutParams) child.getLayoutParams();
169df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int marginLeft = 0;
170df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int marginRight = 0;
171df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int marginTop = 0;
172df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int marginBottom = 0;
173df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                if (mIsRound) {
174df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    // round screen, check boxed, don't use margins on boxed
175df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    if ((lp.boxedEdges & LayoutParams.BOX_LEFT) == 0) {
176df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        marginLeft = lp.leftMargin;
177df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
178df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    if ((lp.boxedEdges & LayoutParams.BOX_RIGHT) == 0) {
179df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        marginRight = lp.rightMargin;
180df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
181df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    if ((lp.boxedEdges & LayoutParams.BOX_TOP) == 0) {
182df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        marginTop = lp.topMargin;
183df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
184df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    if ((lp.boxedEdges & LayoutParams.BOX_BOTTOM) == 0) {
185df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        marginBottom = lp.bottomMargin;
186df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
187df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                } else {
188df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    // rectangular, ignore boxed, use margins
189df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    marginLeft = lp.leftMargin;
190df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    marginTop = lp.topMargin;
191df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    marginRight = lp.rightMargin;
192df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    marginBottom = lp.bottomMargin;
193df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                }
194df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
195df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                maxWidth = Math.max(maxWidth, child.getMeasuredWidth() + marginLeft + marginRight);
196df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                maxHeight = Math.max(maxHeight,
197df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        child.getMeasuredHeight() + marginTop + marginBottom);
198df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childState = combineMeasuredStates(childState, child.getMeasuredState());
199df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
200df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
201df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // Account for padding too
202df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        maxWidth += getPaddingLeft() + mForegroundPadding.left + getPaddingRight()
203df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                + mForegroundPadding.right;
204df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        maxHeight += getPaddingTop() + mForegroundPadding.top + getPaddingBottom()
205df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                + mForegroundPadding.bottom;
206df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
207df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // Check against our minimum height and width
208df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
209df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
210df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
211df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // Check against our foreground's minimum height and width
212df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mForegroundDrawable != null) {
213df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            maxHeight = Math.max(maxHeight, mForegroundDrawable.getMinimumHeight());
214df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            maxWidth = Math.max(maxWidth, mForegroundDrawable.getMinimumWidth());
215df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
216df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
217df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int measuredWidth = resolveSizeAndState(maxWidth, widthMeasureSpec, childState);
218df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int measuredHeight = resolveSizeAndState(maxHeight, heightMeasureSpec,
219df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childState << MEASURED_HEIGHT_STATE_SHIFT);
220df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        setMeasuredDimension(measuredWidth, measuredHeight);
221df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
222df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // determine boxed inset
223d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska        int boxInset = calculateInset(measuredWidth, measuredHeight);
224df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // adjust the the children measures, if necessary
225df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        for (int i = 0; i < count; i++) {
226df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            measureChild(widthMeasureSpec, heightMeasureSpec, boxInset, i);
227df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
228df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
229df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
230df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
231df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
232df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int count = getChildCount();
233df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
234df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int parentLeft = getPaddingLeft() + mForegroundPadding.left;
235df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int parentRight = right - left - getPaddingRight() - mForegroundPadding.right;
236df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
237df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int parentTop = getPaddingTop() + mForegroundPadding.top;
238df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int parentBottom = bottom - top - getPaddingBottom() - mForegroundPadding.bottom;
239df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
240df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        for (int i = 0; i < count; i++) {
241df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            final View child = getChildAt(i);
242df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (child.getVisibility() != GONE) {
243df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
244df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
245df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int width = child.getMeasuredWidth();
246df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int height = child.getMeasuredHeight();
247df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
248df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int childLeft;
249df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int childTop;
250df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
251df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int gravity = lp.gravity;
252df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                if (gravity == -1) {
253df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    gravity = DEFAULT_CHILD_GRAVITY;
254df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                }
255df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
256df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int layoutDirection = getLayoutDirection();
257df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
258df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
259df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
260d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska                int desiredInset = calculateInset(getMeasuredWidth(), getMeasuredHeight());
261df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
262df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                // If the child's width is match_parent then we can ignore gravity.
263df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int leftChildMargin = calculateChildLeftMargin(lp, horizontalGravity, desiredInset);
264df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int rightChildMargin = calculateChildRightMargin(lp, horizontalGravity,
265df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        desiredInset);
266df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                if (lp.width == LayoutParams.MATCH_PARENT) {
267df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    childLeft = parentLeft + leftChildMargin;
268df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                } else {
269df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
270df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.CENTER_HORIZONTAL:
271df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childLeft = parentLeft + (parentRight - parentLeft - width) / 2
272df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                                    + leftChildMargin - rightChildMargin;
273df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            break;
274df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.RIGHT:
275df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childLeft = parentRight - width - rightChildMargin;
276df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            break;
277df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.LEFT:
278df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        default:
279df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childLeft = parentLeft + leftChildMargin;
280df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
281df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                }
282df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
283df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                // If the child's height is match_parent then we can ignore gravity.
284df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int topChildMargin = calculateChildTopMargin(lp, verticalGravity, desiredInset);
285df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                int bottomChildMargin = calculateChildBottomMargin(lp, verticalGravity,
286df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        desiredInset);
287df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                if (lp.height == LayoutParams.MATCH_PARENT) {
288df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    childTop = parentTop + topChildMargin;
289df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                } else {
290df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    switch (verticalGravity) {
291df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.CENTER_VERTICAL:
292df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childTop = parentTop + (parentBottom - parentTop - height) / 2
293df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                                    + topChildMargin - bottomChildMargin;
294df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            break;
295df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.BOTTOM:
296df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childTop = parentBottom - height - bottomChildMargin;
297df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            break;
298df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        case Gravity.TOP:
299df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                        default:
300df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                            childTop = parentTop + topChildMargin;
301df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    }
302df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                }
303df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                child.layout(childLeft, childTop, childLeft + width, childTop + height);
304df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
305df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
306df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
307df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
308df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
309df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
310df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return p instanceof LayoutParams;
311df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
312df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
313df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    @Override
314df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
315df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return new LayoutParams(p);
316df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
317df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
318df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private void measureChild(int widthMeasureSpec, int heightMeasureSpec, int desiredMinInset,
319df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            int i) {
320df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final View child = getChildAt(i);
321df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final LayoutParams childLayoutParams = (LayoutParams) child.getLayoutParams();
322df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
323df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int gravity = childLayoutParams.gravity;
324df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (gravity == -1) {
325df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            gravity = DEFAULT_CHILD_GRAVITY;
326df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
327df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
328df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
329df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
330df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int childWidthMeasureSpec;
331df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int childHeightMeasureSpec;
332df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
333df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int leftParentPadding = getPaddingLeft() + mForegroundPadding.left;
334df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int rightParentPadding = getPaddingRight() + mForegroundPadding.right;
335df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int topParentPadding = getPaddingTop() + mForegroundPadding.top;
336df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int bottomParentPadding = getPaddingBottom() + mForegroundPadding.bottom;
337df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
338df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // adjust width
339df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int totalWidthMargin = leftParentPadding + rightParentPadding + calculateChildLeftMargin(
340df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams, horizontalGravity, desiredMinInset) + calculateChildRightMargin(
341df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams, horizontalGravity, desiredMinInset);
342df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
343df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        // adjust height
344df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int totalHeightMargin = topParentPadding + bottomParentPadding + calculateChildTopMargin(
345df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams, verticalGravity, desiredMinInset) + calculateChildBottomMargin(
346df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams, verticalGravity, desiredMinInset);
347df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
348df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, totalWidthMargin,
349df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams.width);
350df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, totalHeightMargin,
351df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                childLayoutParams.height);
352df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
353df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int maxAllowedWidth = getMeasuredWidth() - totalWidthMargin;
354df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        int maxAllowedHeight = getMeasuredHeight() - totalHeightMargin;
355df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (child.getMeasuredWidth() > maxAllowedWidth
356df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                || child.getMeasuredHeight() > maxAllowedHeight) {
357df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
358df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
359df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
360df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
361df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private int calculateChildLeftMargin(LayoutParams lp, int horizontalGravity, int
362df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            desiredMinInset) {
363df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_LEFT) != 0)) {
364df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (lp.width == LayoutParams.MATCH_PARENT || horizontalGravity == Gravity.LEFT) {
365df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                return lp.leftMargin + desiredMinInset;
366df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
367df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
368df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return lp.leftMargin;
369df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
370df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
371df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private int calculateChildRightMargin(LayoutParams lp, int horizontalGravity, int
372df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            desiredMinInset) {
373df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_RIGHT) != 0)) {
374df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (lp.width == LayoutParams.MATCH_PARENT || horizontalGravity == Gravity.RIGHT) {
375df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                return lp.rightMargin + desiredMinInset;
376df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
377df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
378df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return lp.rightMargin;
379df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
380df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
381df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private int calculateChildTopMargin(LayoutParams lp, int verticalGravity, int desiredMinInset) {
382df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_TOP) != 0)) {
383df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (lp.height == LayoutParams.MATCH_PARENT || verticalGravity == Gravity.TOP) {
384df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                return lp.topMargin + desiredMinInset;
385df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
386df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
387df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return lp.topMargin;
388df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
389df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
390df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    private int calculateChildBottomMargin(LayoutParams lp, int verticalGravity, int
391df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            desiredMinInset) {
392df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_BOTTOM) != 0)) {
393df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            if (lp.height == LayoutParams.MATCH_PARENT || verticalGravity == Gravity.BOTTOM) {
394df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                return lp.bottomMargin + desiredMinInset;
395df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            }
396df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
397df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return lp.bottomMargin;
398df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
399df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
400d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska    private int calculateInset(int measuredWidth, int measuredHeight) {
401d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska        int rightEdge = Math.min(measuredWidth, mScreenWidth);
402d721b0070afd55b2c0cac1f7eced9652277d77a9Aga Madurska        int bottomEdge = Math.min(measuredHeight, mScreenHeight);
403df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        return (int) (FACTOR * Math.max(rightEdge, bottomEdge));
404df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
405df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
406df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    /**
407df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * Per-child layout information for layouts that support margins, gravity and boxedEdges.
408df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * See {@link R.styleable#BoxInsetLayout_Layout BoxInsetLayout Layout Attributes} for a list
409df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * of all child view attributes that this class supports.
410df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     *
411df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     * @attr ref R.styleable#BoxInsetLayout_Layout_boxedEdges
412df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska     */
413df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    public static class LayoutParams extends FrameLayout.LayoutParams {
414df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
415df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** @hide */
41621061fa807a55ee22f733683cc3c33c87c484f69Aga Madurska        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
417df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        @IntDef({BOX_NONE, BOX_LEFT, BOX_TOP, BOX_RIGHT, BOX_BOTTOM, BOX_ALL})
418df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        @Retention(RetentionPolicy.SOURCE)
419df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public @interface BoxedEdges {}
420df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
421df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** Default boxing setting. There are no insets forced on the child views. */
422df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_NONE = 0x0;
423df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** The view will force an inset on the left edge of the children. */
424df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_LEFT = 0x01;
425df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** The view will force an inset on the top edge of the children. */
426df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_TOP = 0x02;
427df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** The view will force an inset on the right edge of the children. */
428df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_RIGHT = 0x04;
429df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** The view will force an inset on the bottom edge of the children. */
430df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_BOTTOM = 0x08;
431df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** The view will force an inset on all of the edges of the children. */
432df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public static final int BOX_ALL = 0x0F;
433df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
434df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /** Specifies the screen-specific insets for each of the child edges. */
435df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        @BoxedEdges
436df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public int boxedEdges = BOX_NONE;
437df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
438df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
439df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Creates a new set of layout parameters. The values are extracted from the supplied
440df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * attributes set and context.
441df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
442df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param context the application environment
443df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param attrs the set of attributes from which to extract the layout parameters' values
444df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
445df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        @SuppressWarnings("ResourceType")
446df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(@NonNull Context context, @Nullable AttributeSet attrs) {
447df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(context, attrs);
448df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoxInsetLayout_Layout,
449df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska                    0, 0);
450df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            boxedEdges = a.getInt(R.styleable.BoxInsetLayout_Layout_boxedEdges, BOX_NONE);
451df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            a.recycle();
452df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
453df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
454df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
455df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Creates a new set of layout parameters with the specified width and height.
456df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
457df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param width the width, either {@link #MATCH_PARENT},
458df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *              {@link #WRAP_CONTENT} or a fixed size in pixels
459df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param height the height, either {@link #MATCH_PARENT},
460df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *               {@link #WRAP_CONTENT} or a fixed size in pixelsy
461df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
462df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(int width, int height) {
463df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(width, height);
464df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
465df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
466df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
467df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Creates a new set of layout parameters with the specified width, height
468df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * and gravity.
469df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
470df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param width the width, either {@link #MATCH_PARENT},
471df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *              {@link #WRAP_CONTENT} or a fixed size in pixels
472df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param height the height, either {@link #MATCH_PARENT},
473df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *               {@link #WRAP_CONTENT} or a fixed size in pixels
474df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param gravity the gravity
475df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
476df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @see android.view.Gravity
477df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
478df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(int width, int height, int gravity) {
479df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(width, height, gravity);
480df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
481df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
482df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
483df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(int width, int height, int gravity, @BoxedEdges int boxed) {
484df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(width, height, gravity);
485df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            boxedEdges = boxed;
486df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
487df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
488df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
489df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Copy constructor. Clones the width and height of the source.
490df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
491df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param source The layout params to copy from.
492df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
493df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(@NonNull ViewGroup.LayoutParams source) {
494df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(source);
495df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
496df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
497df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
498df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Copy constructor. Clones the width, height and margin values.
499df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
500df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param source The layout params to copy from.
501df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
502df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(@NonNull ViewGroup.MarginLayoutParams source) {
503df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(source);
504df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
505df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
506df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
507df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Copy constructor. Clones the width, height, margin values, and
508df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * gravity of the source.
509df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
510df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param source The layout params to copy from.
511df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
512df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(@NonNull FrameLayout.LayoutParams source) {
513df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(source);
514df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
515df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska
516df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        /**
517df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * Copy constructor. Clones the width, height, margin values, boxedEdges and
518df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * gravity of the source.
519df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         *
520df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         * @param source The layout params to copy from.
521df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska         */
522df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        public LayoutParams(@NonNull LayoutParams source) {
523df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            super(source);
524df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            this.boxedEdges = source.boxedEdges;
525df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska            this.gravity = source.gravity;
526df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska        }
527df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska    }
528df451a01e367bfb64485b669f6e4331c8c563d3fAga Madurska}
529