blob: bd4199264882b4479f6534e1e19996e05fde83d9 [file] [log] [blame]
Winson Chung94804152015-05-08 13:06:44 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
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.android.launcher3;
18
19import android.content.Context;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080020import android.content.res.TypedArray;
Winson Chung94804152015-05-08 13:06:44 -070021import android.graphics.Rect;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080022import android.graphics.drawable.Drawable;
23import android.graphics.drawable.InsetDrawable;
Winson Chung94804152015-05-08 13:06:44 -070024import android.util.AttributeSet;
Winson Chung73f0b9b2015-07-08 14:13:08 -070025import android.util.Log;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080026import android.view.View;
27import android.widget.FrameLayout;
Winson Chung94804152015-05-08 13:06:44 -070028
Sunny Goyal6c56c682015-07-16 14:09:05 -070029import com.android.launcher3.config.ProviderConfig;
30
Winson Chung94804152015-05-08 13:06:44 -070031/**
32 * A base container view, which supports resizing.
33 */
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080034public abstract class BaseContainerView extends FrameLayout implements Insettable {
Winson Chung94804152015-05-08 13:06:44 -070035
Winson Chung73f0b9b2015-07-08 14:13:08 -070036 private final static String TAG = "BaseContainerView";
37
Winson Chungef7f8742015-06-04 17:18:17 -070038 // The window insets
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080039 private final Rect mInsets = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070040 // The bounds of the search bar. Only the left, top, right are used to inset the
41 // search bar and the height is determined by the measurement of the layout
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080042 private final Rect mFixedSearchBarBounds = new Rect();
Winsonb0ca1a22015-08-06 14:42:50 -070043 // The computed padding to apply to the container to achieve the container bounds
Sunny Goyal94f46d92016-02-16 14:56:33 -080044 protected final Rect mContentPadding = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070045 // The inset to apply to the edges and between the search bar and the container
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080046 private final int mContainerBoundsInset;
47
48 private final Drawable mRevealDrawable;
49
50 private View mRevealView;
51 private View mContent;
Winson Chung94804152015-05-08 13:06:44 -070052
53 public BaseContainerView(Context context) {
54 this(context, null);
55 }
56
57 public BaseContainerView(Context context, AttributeSet attrs) {
58 this(context, attrs, 0);
59 }
60
61 public BaseContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
62 super(context, attrs, defStyleAttr);
Winson Chungef7f8742015-06-04 17:18:17 -070063 mContainerBoundsInset = getResources().getDimensionPixelSize(R.dimen.container_bounds_inset);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080064
65 TypedArray a = context.obtainStyledAttributes(attrs,
66 R.styleable.BaseContainerView, defStyleAttr, 0);
67 mRevealDrawable = a.getDrawable(R.styleable.BaseContainerView_revealBackground);
68 a.recycle();
69 }
70
71 @Override
72 protected void onFinishInflate() {
73 super.onFinishInflate();
74
75 mContent = findViewById(R.id.main_content);
76 mRevealView = findViewById(R.id.reveal_view);
Winson Chung94804152015-05-08 13:06:44 -070077 }
78
79 @Override
80 final public void setInsets(Rect insets) {
81 mInsets.set(insets);
Winson Chungef7f8742015-06-04 17:18:17 -070082 updateBackgroundAndPaddings();
83 }
84
Winson Chung94804152015-05-08 13:06:44 -070085 /**
Winson Chungef7f8742015-06-04 17:18:17 -070086 * Sets the search bar bounds for this container view to match.
Winson Chung94804152015-05-08 13:06:44 -070087 */
Winson Chungef7f8742015-06-04 17:18:17 -070088 final public void setSearchBarBounds(Rect bounds) {
Sunny Goyal6c56c682015-07-16 14:09:05 -070089 if (ProviderConfig.IS_DOGFOOD_BUILD && !isValidSearchBarBounds(bounds)) {
Winson Chung73f0b9b2015-07-08 14:13:08 -070090 Log.e(TAG, "Invalid search bar bounds: " + bounds);
91 }
92
93 mFixedSearchBarBounds.set(bounds);
Winson Chungef7f8742015-06-04 17:18:17 -070094
Winson Chung94804152015-05-08 13:06:44 -070095 // Post the updates since they can trigger a relayout, and this call can be triggered from
96 // a layout pass itself.
97 post(new Runnable() {
98 @Override
99 public void run() {
Winson Chungef7f8742015-06-04 17:18:17 -0700100 updateBackgroundAndPaddings();
Winson Chung94804152015-05-08 13:06:44 -0700101 }
102 });
103 }
104
105 /**
Winson Chungef7f8742015-06-04 17:18:17 -0700106 * Update the backgrounds and padding in response to a change in the bounds or insets.
Winson Chung94804152015-05-08 13:06:44 -0700107 */
Winson Chungef7f8742015-06-04 17:18:17 -0700108 protected void updateBackgroundAndPaddings() {
109 Rect padding;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800110 if (isValidSearchBarBounds(mFixedSearchBarBounds)) {
111 padding = new Rect(
112 mFixedSearchBarBounds.left,
Winson Chungef7f8742015-06-04 17:18:17 -0700113 mInsets.top + mContainerBoundsInset,
Winson Chung73f0b9b2015-07-08 14:13:08 -0700114 getMeasuredWidth() - mFixedSearchBarBounds.right,
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800115 mInsets.bottom + mContainerBoundsInset
116 );
117 } else {
118 padding = new Rect(
119 mInsets.left + mContainerBoundsInset,
120 mInsets.top + mContainerBoundsInset,
121 mInsets.right + mContainerBoundsInset,
122 mInsets.bottom + mContainerBoundsInset
123 );
Winson Chungef7f8742015-06-04 17:18:17 -0700124 }
Winsonb0ca1a22015-08-06 14:42:50 -0700125
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800126 // The container padding changed, notify the container.
127 if (!padding.equals(mContentPadding)) {
Winson Chungef7f8742015-06-04 17:18:17 -0700128 mContentPadding.set(padding);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800129 onUpdateBackgroundAndPaddings(padding);
Winson Chungef7f8742015-06-04 17:18:17 -0700130 }
Winson Chung94804152015-05-08 13:06:44 -0700131 }
132
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800133 private void onUpdateBackgroundAndPaddings(Rect padding) {
134 // Apply the top-bottom padding to itself so that the launcher transition is
135 // clipped correctly
136 setPadding(0, padding.top, 0, padding.bottom);
137
138 InsetDrawable background = new InsetDrawable(mRevealDrawable,
139 padding.left, 0, padding.right, 0);
140 mRevealView.setBackground(background.getConstantState().newDrawable());
141 mContent.setBackground(background);
142
Sunny Goyala6194d32016-02-19 09:34:09 -0800143 // We let the content have a intent background, but still have full width.
144 // This allows the scroll bar to be used responsive outside the background bounds as well.
145 mContent.setPadding(0, 0, 0, 0);
146
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800147 Rect bgPadding = new Rect();
148 background.getPadding(bgPadding);
149 onUpdateBgPadding(padding, bgPadding);
150 }
151
152 protected abstract void onUpdateBgPadding(Rect padding, Rect bgPadding);
Winson Chung73f0b9b2015-07-08 14:13:08 -0700153
154 /**
155 * Returns whether the search bar bounds we got are considered valid.
156 */
157 private boolean isValidSearchBarBounds(Rect searchBarBounds) {
158 return !searchBarBounds.isEmpty() &&
159 searchBarBounds.right <= getMeasuredWidth() &&
160 searchBarBounds.bottom <= getMeasuredHeight();
161 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800162
163 public final View getContentView() {
164 return mContent;
165 }
166
167 public final View getRevealView() {
168 return mRevealView;
169 }
Winson Chung94804152015-05-08 13:06:44 -0700170}