blob: 18393c5ec0f533a40cbfcff2547746b2aaf3b5c7 [file] [log] [blame]
Dirk Vogt74af2bf2016-05-31 11:21:46 +02001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.fairphone.setupwizard.ui.widget;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.Canvas;
22import android.graphics.Rect;
23import android.graphics.drawable.Drawable;
24import android.support.v4.view.ViewCompat;
25import android.util.AttributeSet;
26import android.widget.FrameLayout;
27
28import com.fairphone.setupwizard.R;
29
30/**
31 * A layout that draws something in the insets passed to {@link #fitSystemWindows(android.graphics.Rect)}, i.e. the area above UI chrome
32 * (status and navigation bars, overlay action bars).
33 */
34public class ScrimInsetsFrameLayout extends FrameLayout {
35 private Drawable mInsetForeground;
36
37 private Rect mInsets;
38 private Rect mTempRect = new Rect();
39 private OnInsetsCallback mOnInsetsCallback;
40
41 public ScrimInsetsFrameLayout(Context context) {
42 super(context);
43 init(context, null, 0);
44 }
45
46 public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
47 super(context, attrs);
48 init(context, attrs, 0);
49 }
50
51 public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
52 super(context, attrs, defStyle);
53 init(context, attrs, defStyle);
54 }
55
56 private void init(Context context, AttributeSet attrs, int defStyle) {
57 final TypedArray a = context.obtainStyledAttributes(attrs,
58 R.styleable.ScrimInsetsView, defStyle, 0);
59 if (a == null) {
60 return;
61 }
62 mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
63 a.recycle();
64
65 setWillNotDraw(true);
66 }
67
68 @Override
69 protected boolean fitSystemWindows(Rect insets) {
70 mInsets = new Rect(insets);
71 setWillNotDraw(mInsetForeground == null);
72 ViewCompat.postInvalidateOnAnimation(this);
73 if (mOnInsetsCallback != null) {
74 mOnInsetsCallback.onInsetsChanged(insets);
75 }
76 return true; // consume insets
77 }
78
79 @Override
80 public void draw(Canvas canvas) {
81 super.draw(canvas);
82
83 int width = getWidth();
84 int height = getHeight();
85 if (mInsets != null && mInsetForeground != null) {
86 int sc = canvas.save();
87 canvas.translate(getScrollX(), getScrollY());
88
89 // Top
90 mTempRect.set(0, 0, width, mInsets.top);
91 mInsetForeground.setBounds(mTempRect);
92 mInsetForeground.draw(canvas);
93
94 // Bottom
95 mTempRect.set(0, height - mInsets.bottom, width, height);
96 mInsetForeground.setBounds(mTempRect);
97 mInsetForeground.draw(canvas);
98
99 // Left
100 mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
101 mInsetForeground.setBounds(mTempRect);
102 mInsetForeground.draw(canvas);
103
104 // Right
105 mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
106 mInsetForeground.setBounds(mTempRect);
107 mInsetForeground.draw(canvas);
108
109 canvas.restoreToCount(sc);
110 }
111 }
112
113 @Override
114 protected void onAttachedToWindow() {
115 super.onAttachedToWindow();
116 if (mInsetForeground != null) {
117 mInsetForeground.setCallback(this);
118 }
119 }
120
121 @Override
122 protected void onDetachedFromWindow() {
123 super.onDetachedFromWindow();
124 if (mInsetForeground != null) {
125 mInsetForeground.setCallback(null);
126 }
127 }
128
129 /**
130 * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
131 * {@link #fitSystemWindows(android.graphics.Rect)} is called. This is useful for setting padding on UI elements based on
132 * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
133 * clipToPadding to false.
134 */
135 public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
136 mOnInsetsCallback = onInsetsCallback;
137 }
138
139 public static interface OnInsetsCallback {
140 public void onInsetsChanged(Rect insets);
141 }
142}