131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/*
231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Copyright (C) 2015 The Android Open Source Project
331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License");
531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * you may not use this file except in compliance with the License.
631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * You may obtain a copy of the License at
731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *      http://www.apache.org/licenses/LICENSE-2.0
931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
1031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Unless required by applicable law or agreed to in writing, software
1131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS,
1231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * See the License for the specific language governing permissions and
1431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * limitations under the License.
1531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */
1631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
1731a49efe2adb59e31611f6871895a3243d835127Yuichi Arakipackage android.support.design.internal;
1831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
2131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.Context;
2231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.res.TypedArray;
2331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.Canvas;
2431a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.Rect;
2531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.drawable.Drawable;
2631a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.annotation.NonNull;
27c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo;
2831a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.R;
2931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v4.view.ViewCompat;
3031a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v4.view.WindowInsetsCompat;
3131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.util.AttributeSet;
3231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.View;
3331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.widget.FrameLayout;
3431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
3531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/**
3631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * @hide
3731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */
388e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP)
3931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakipublic class ScrimInsetsFrameLayout extends FrameLayout {
4031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
41657ea1100fee4750f148f9d0dcb7e7e2028f105eAurimas Liutikas    Drawable mInsetForeground;
4231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
43657ea1100fee4750f148f9d0dcb7e7e2028f105eAurimas Liutikas    Rect mInsets;
4431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private Rect mTempRect = new Rect();
4631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context) {
4831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        this(context, null);
4931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
5031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
5231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        this(context, attrs, 0);
5331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
5431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
5631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super(context, attrs, defStyleAttr);
5731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        final TypedArray a = context.obtainStyledAttributes(attrs,
5931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                R.styleable.ScrimInsetsFrameLayout, defStyleAttr,
6031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                R.style.Widget_Design_ScrimInsetsFrameLayout);
6131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground);
6231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        a.recycle();
6331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        setWillNotDraw(true); // No need to draw until the insets are adjusted
6431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
6531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        ViewCompat.setOnApplyWindowInsetsListener(this,
6631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                new android.support.v4.view.OnApplyWindowInsetsListener() {
6731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    @Override
6831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    public WindowInsetsCompat onApplyWindowInsets(View v,
6931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                            WindowInsetsCompat insets) {
7031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        if (null == mInsets) {
7131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                            mInsets = new Rect();
7231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        }
7331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        mInsets.set(insets.getSystemWindowInsetLeft(),
7431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetTop(),
7531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetRight(),
7631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetBottom());
77e57300cbdb4247da95e95059ad27a348a56477c6Yuichi Araki                        onInsetsChanged(insets);
789c937474b223328601b3c4cb3fa236971c721b2eYuichi Araki                        setWillNotDraw(!insets.hasSystemWindowInsets() || mInsetForeground == null);
7931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        ViewCompat.postInvalidateOnAnimation(ScrimInsetsFrameLayout.this);
8031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        return insets.consumeSystemWindowInsets();
8131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    }
8231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                });
8331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
8431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
8531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
8631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void draw(@NonNull Canvas canvas) {
8731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.draw(canvas);
8831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
8931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        int width = getWidth();
9031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        int height = getHeight();
9131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsets != null && mInsetForeground != null) {
9231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            int sc = canvas.save();
9331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            canvas.translate(getScrollX(), getScrollY());
9431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
9531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Top
9631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, 0, width, mInsets.top);
9731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
9831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
9931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
10031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Bottom
10131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, height - mInsets.bottom, width, height);
10231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
10331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
10431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
10531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Left
10631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
10731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
10831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
10931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Right
11131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
11231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
11331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
11431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            canvas.restoreToCount(sc);
11631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
11731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
11831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
12031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    protected void onAttachedToWindow() {
12131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.onAttachedToWindow();
12231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsetForeground != null) {
12331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setCallback(this);
12431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
12531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
12631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
12731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
12831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    protected void onDetachedFromWindow() {
12931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.onDetachedFromWindow();
13031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsetForeground != null) {
13131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setCallback(null);
13231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
13331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
13431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
135e57300cbdb4247da95e95059ad27a348a56477c6Yuichi Araki    protected void onInsetsChanged(WindowInsetsCompat insets) {
13630d42dc19655e637644adc3846025027240bf0afYuichi Araki    }
13730d42dc19655e637644adc3846025027240bf0afYuichi Araki
13831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki}
139