blob: b8e7b63feeda83989958349a808f5123fdd21685 [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
29/**
30 * A base container view, which supports resizing.
31 */
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080032public abstract class BaseContainerView extends FrameLayout implements Insettable {
Winson Chung94804152015-05-08 13:06:44 -070033
Winson Chung73f0b9b2015-07-08 14:13:08 -070034 private final static String TAG = "BaseContainerView";
35
Winson Chungef7f8742015-06-04 17:18:17 -070036 // The window insets
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080037 private final Rect mInsets = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070038 // The bounds of the search bar. Only the left, top, right are used to inset the
39 // search bar and the height is determined by the measurement of the layout
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080040 private final Rect mFixedSearchBarBounds = new Rect();
Winsonb0ca1a22015-08-06 14:42:50 -070041 // The computed padding to apply to the container to achieve the container bounds
Sunny Goyal94f46d92016-02-16 14:56:33 -080042 protected final Rect mContentPadding = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070043 // The inset to apply to the edges and between the search bar and the container
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080044 private final int mContainerBoundsInset;
45
46 private final Drawable mRevealDrawable;
47
48 private View mRevealView;
49 private View mContent;
Winson Chung94804152015-05-08 13:06:44 -070050
51 public BaseContainerView(Context context) {
52 this(context, null);
53 }
54
55 public BaseContainerView(Context context, AttributeSet attrs) {
56 this(context, attrs, 0);
57 }
58
59 public BaseContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
60 super(context, attrs, defStyleAttr);
Winson Chungef7f8742015-06-04 17:18:17 -070061 mContainerBoundsInset = getResources().getDimensionPixelSize(R.dimen.container_bounds_inset);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080062
63 TypedArray a = context.obtainStyledAttributes(attrs,
64 R.styleable.BaseContainerView, defStyleAttr, 0);
65 mRevealDrawable = a.getDrawable(R.styleable.BaseContainerView_revealBackground);
66 a.recycle();
67 }
68
69 @Override
70 protected void onFinishInflate() {
71 super.onFinishInflate();
72
73 mContent = findViewById(R.id.main_content);
74 mRevealView = findViewById(R.id.reveal_view);
Winson Chung94804152015-05-08 13:06:44 -070075 }
76
77 @Override
78 final public void setInsets(Rect insets) {
79 mInsets.set(insets);
Winson Chungef7f8742015-06-04 17:18:17 -070080 updateBackgroundAndPaddings();
81 }
82
Winson Chung94804152015-05-08 13:06:44 -070083 /**
Winson Chungef7f8742015-06-04 17:18:17 -070084 * Sets the search bar bounds for this container view to match.
Winson Chung94804152015-05-08 13:06:44 -070085 */
Winson Chungef7f8742015-06-04 17:18:17 -070086 final public void setSearchBarBounds(Rect bounds) {
Winson Chung73f0b9b2015-07-08 14:13:08 -070087 if (LauncherAppState.isDogfoodBuild() && !isValidSearchBarBounds(bounds)) {
88 Log.e(TAG, "Invalid search bar bounds: " + bounds);
89 }
90
91 mFixedSearchBarBounds.set(bounds);
Winson Chungef7f8742015-06-04 17:18:17 -070092
Winson Chung94804152015-05-08 13:06:44 -070093 // Post the updates since they can trigger a relayout, and this call can be triggered from
94 // a layout pass itself.
95 post(new Runnable() {
96 @Override
97 public void run() {
Winson Chungef7f8742015-06-04 17:18:17 -070098 updateBackgroundAndPaddings();
Winson Chung94804152015-05-08 13:06:44 -070099 }
100 });
101 }
102
103 /**
Winson Chungef7f8742015-06-04 17:18:17 -0700104 * Update the backgrounds and padding in response to a change in the bounds or insets.
Winson Chung94804152015-05-08 13:06:44 -0700105 */
Winson Chungef7f8742015-06-04 17:18:17 -0700106 protected void updateBackgroundAndPaddings() {
107 Rect padding;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800108 if (isValidSearchBarBounds(mFixedSearchBarBounds)) {
109 padding = new Rect(
110 mFixedSearchBarBounds.left,
Winson Chungef7f8742015-06-04 17:18:17 -0700111 mInsets.top + mContainerBoundsInset,
Winson Chung73f0b9b2015-07-08 14:13:08 -0700112 getMeasuredWidth() - mFixedSearchBarBounds.right,
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800113 mInsets.bottom + mContainerBoundsInset
114 );
115 } else {
116 padding = new Rect(
117 mInsets.left + mContainerBoundsInset,
118 mInsets.top + mContainerBoundsInset,
119 mInsets.right + mContainerBoundsInset,
120 mInsets.bottom + mContainerBoundsInset
121 );
Winson Chungef7f8742015-06-04 17:18:17 -0700122 }
Winsonb0ca1a22015-08-06 14:42:50 -0700123
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800124 // The container padding changed, notify the container.
125 if (!padding.equals(mContentPadding)) {
Winson Chungef7f8742015-06-04 17:18:17 -0700126 mContentPadding.set(padding);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800127 onUpdateBackgroundAndPaddings(padding);
Winson Chungef7f8742015-06-04 17:18:17 -0700128 }
Winson Chung94804152015-05-08 13:06:44 -0700129 }
130
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800131 private void onUpdateBackgroundAndPaddings(Rect padding) {
132 // Apply the top-bottom padding to itself so that the launcher transition is
133 // clipped correctly
134 setPadding(0, padding.top, 0, padding.bottom);
135
136 InsetDrawable background = new InsetDrawable(mRevealDrawable,
137 padding.left, 0, padding.right, 0);
138 mRevealView.setBackground(background.getConstantState().newDrawable());
139 mContent.setBackground(background);
140
141 Rect bgPadding = new Rect();
142 background.getPadding(bgPadding);
143 onUpdateBgPadding(padding, bgPadding);
144 }
145
146 protected abstract void onUpdateBgPadding(Rect padding, Rect bgPadding);
Winson Chung73f0b9b2015-07-08 14:13:08 -0700147
148 /**
149 * Returns whether the search bar bounds we got are considered valid.
150 */
151 private boolean isValidSearchBarBounds(Rect searchBarBounds) {
152 return !searchBarBounds.isEmpty() &&
153 searchBarBounds.right <= getMeasuredWidth() &&
154 searchBarBounds.bottom <= getMeasuredHeight();
155 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800156
157 public final View getContentView() {
158 return mContent;
159 }
160
161 public final View getRevealView() {
162 return mRevealView;
163 }
Winson Chung94804152015-05-08 13:06:44 -0700164}