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
1931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.Context;
2031a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.res.TypedArray;
2131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.Canvas;
2231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.Rect;
2331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.graphics.drawable.Drawable;
2431a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.annotation.NonNull;
2531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.R;
2631a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v4.view.ViewCompat;
2731a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v4.view.WindowInsetsCompat;
2831a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.util.AttributeSet;
2931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.View;
3031a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.widget.FrameLayout;
3131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
3231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/**
3331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * @hide
3431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */
3531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakipublic class ScrimInsetsFrameLayout extends FrameLayout {
3631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
3731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private Drawable mInsetForeground;
3831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
3931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private Rect mInsets;
4031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private Rect mTempRect = new Rect();
4231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context) {
4431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        this(context, null);
4531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
4631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
4831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        this(context, attrs, 0);
4931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
5031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
5231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super(context, attrs, defStyleAttr);
5331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        final TypedArray a = context.obtainStyledAttributes(attrs,
5531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                R.styleable.ScrimInsetsFrameLayout, defStyleAttr,
5631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                R.style.Widget_Design_ScrimInsetsFrameLayout);
5731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground);
5831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        a.recycle();
5931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        setWillNotDraw(true); // No need to draw until the insets are adjusted
6031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
6131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        ViewCompat.setOnApplyWindowInsetsListener(this,
6231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                new android.support.v4.view.OnApplyWindowInsetsListener() {
6331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    @Override
6431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    public WindowInsetsCompat onApplyWindowInsets(View v,
6531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                            WindowInsetsCompat insets) {
6631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        if (null == mInsets) {
6731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                            mInsets = new Rect();
6831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        }
6931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        mInsets.set(insets.getSystemWindowInsetLeft(),
7031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetTop(),
7131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetRight(),
7231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                                insets.getSystemWindowInsetBottom());
7330d42dc19655e637644adc3846025027240bf0afYuichi Araki                        onInsetsChanged(mInsets);
7431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        setWillNotDraw(mInsets.isEmpty() || mInsetForeground == null);
7531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        ViewCompat.postInvalidateOnAnimation(ScrimInsetsFrameLayout.this);
7631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                        return insets.consumeSystemWindowInsets();
7731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                    }
7831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                });
7931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
8031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
8131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
8231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void draw(@NonNull Canvas canvas) {
8331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.draw(canvas);
8431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
8531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        int width = getWidth();
8631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        int height = getHeight();
8731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsets != null && mInsetForeground != null) {
8831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            int sc = canvas.save();
8931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            canvas.translate(getScrollX(), getScrollY());
9031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
9131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Top
9231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, 0, width, mInsets.top);
9331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
9431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
9531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
9631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Bottom
9731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, height - mInsets.bottom, width, height);
9831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
9931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
10031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
10131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Left
10231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
10331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
10431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
10531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
10631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            // Right
10731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
10831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setBounds(mTempRect);
10931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.draw(canvas);
11031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            canvas.restoreToCount(sc);
11231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
11331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
11431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
11631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    protected void onAttachedToWindow() {
11731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.onAttachedToWindow();
11831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsetForeground != null) {
11931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setCallback(this);
12031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
12131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
12231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
12331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
12431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    protected void onDetachedFromWindow() {
12531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        super.onDetachedFromWindow();
12631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mInsetForeground != null) {
12731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mInsetForeground.setCallback(null);
12831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
12931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
13031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
13130d42dc19655e637644adc3846025027240bf0afYuichi Araki    protected void onInsetsChanged(Rect insets) {
13230d42dc19655e637644adc3846025027240bf0afYuichi Araki    }
13330d42dc19655e637644adc3846025027240bf0afYuichi Araki
13431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki}
135