blob: 978c6d82ce1126e994c3ba11ed78b214f4867811 [file] [log] [blame]
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -07001/*
2 * Copyright (C) 2017 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 */
Steven Ng2f5648a2021-02-08 17:18:25 +000016package com.android.launcher3.widget.picker;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070017
Sunny Goyalf3ac7032020-03-13 13:01:33 -070018import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
vadimt9f48a8e2019-12-11 11:52:37 -080019import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
20
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070021import android.animation.Animator;
22import android.animation.AnimatorListenerAdapter;
23import android.animation.PropertyValuesHolder;
24import android.content.Context;
Steven Ng391404f2021-02-17 15:58:23 +000025import android.content.pm.LauncherApps;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070026import android.graphics.Rect;
Steven Ng391404f2021-02-17 15:58:23 +000027import android.os.Process;
28import android.os.UserHandle;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070029import android.util.AttributeSet;
Sunny Goyalde753212018-05-15 13:55:57 -070030import android.util.Pair;
Steven Ng391404f2021-02-17 15:58:23 +000031import android.util.SparseArray;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070032import android.view.LayoutInflater;
33import android.view.MotionEvent;
Sunny Goyalde753212018-05-15 13:55:57 -070034import android.view.View;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070035import android.view.animation.AnimationUtils;
Sunny Goyalf3ac7032020-03-13 13:01:33 -070036import android.view.animation.Interpolator;
Steven Ng167f81b2021-02-23 10:48:46 +000037import android.widget.EditText;
38import android.widget.TextView;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070039
Steven Ng391404f2021-02-17 15:58:23 +000040import androidx.annotation.Nullable;
Tony Wickham9791bd12019-04-05 13:52:35 -070041import androidx.annotation.VisibleForTesting;
Steven Ng391404f2021-02-17 15:58:23 +000042import androidx.recyclerview.widget.RecyclerView;
Tony Wickham9791bd12019-04-05 13:52:35 -070043
Steven Nge8d92342021-02-19 21:29:18 +000044import com.android.launcher3.DeviceProfile;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070045import com.android.launcher3.Insettable;
46import com.android.launcher3.Launcher;
47import com.android.launcher3.LauncherAppState;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070048import com.android.launcher3.R;
Sunny Goyalf3ac7032020-03-13 13:01:33 -070049import com.android.launcher3.anim.PendingAnimation;
vadimt9f48a8e2019-12-11 11:52:37 -080050import com.android.launcher3.compat.AccessibilityManagerCompat;
Sunny Goyal3661bfa2018-03-01 16:29:15 -080051import com.android.launcher3.views.RecyclerViewFastScroller;
52import com.android.launcher3.views.TopRoundedCornerView;
Steven Ng2f5648a2021-02-08 17:18:25 +000053import com.android.launcher3.widget.BaseWidgetSheet;
Yogisha Dixit741fae92021-02-22 14:03:44 +000054import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener;
Steven Ng391404f2021-02-17 15:58:23 +000055import com.android.launcher3.widget.model.WidgetsListBaseEntry;
56import com.android.launcher3.workprofile.PersonalWorkPagedView;
57import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
58
59import java.util.List;
60import java.util.function.Predicate;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070061
62/**
63 * Popup for showing the full list of available widgets
64 */
65public class WidgetsFullSheet extends BaseWidgetSheet
Steven Ng167f81b2021-02-23 10:48:46 +000066 implements Insettable, ProviderChangedListener, OnActivePageChangedListener,
67 WidgetsRecyclerView.HeaderViewDimensionsProvider {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070068
69 private static final long DEFAULT_OPEN_DURATION = 267;
70 private static final long FADE_IN_DURATION = 150;
71 private static final float VERTICAL_START_POSITION = 0.3f;
72
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070073 private final Rect mInsets = new Rect();
Steven Ng391404f2021-02-17 15:58:23 +000074 private final boolean mHasWorkProfile;
75 private final SparseArray<AdapterHolder> mAdapters = new SparseArray();
76 private final UserHandle mCurrentUser = Process.myUserHandle();
77 private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter = entry ->
78 mCurrentUser.equals(entry.mPkgItem.user);
79 private final Predicate<WidgetsListBaseEntry> mWorkWidgetsFilter =
80 mPrimaryWidgetsFilter.negate();
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070081
Steven Ng391404f2021-02-17 15:58:23 +000082 @Nullable private PersonalWorkPagedView mViewPager;
Steven Ng167f81b2021-02-23 10:48:46 +000083 private int mInitialTabsHeight = 0;
84 private View mTabsView;
Steven Ngd73d6e52021-03-09 22:44:04 +000085 private TextView mNoWidgetsView;
Steven Ng167f81b2021-02-23 10:48:46 +000086 private SearchAndRecommendationViewHolder mSearchAndRecommendationViewHolder;
87 private SearchAndRecommendationsScrollController mSearchAndRecommendationsScrollController;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070088
89 public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
90 super(context, attrs, defStyleAttr);
Steven Ng391404f2021-02-17 15:58:23 +000091 mHasWorkProfile = context.getSystemService(LauncherApps.class).getProfiles().size() > 1;
92 mAdapters.put(AdapterHolder.PRIMARY, new AdapterHolder(AdapterHolder.PRIMARY));
93 mAdapters.put(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070094 }
95
96 public WidgetsFullSheet(Context context, AttributeSet attrs) {
97 this(context, attrs, 0);
98 }
99
100 @Override
101 protected void onFinishInflate() {
102 super.onFinishInflate();
103 mContent = findViewById(R.id.container);
Sunny Goyal016d7e92018-03-09 11:09:20 -0800104 TopRoundedCornerView springLayout = (TopRoundedCornerView) mContent;
Steven Ng391404f2021-02-17 15:58:23 +0000105
106 LayoutInflater layoutInflater = LayoutInflater.from(getContext());
107 int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_full_sheet_paged_view
108 : R.layout.widgets_full_sheet_recyclerview;
Steven Ng167f81b2021-02-23 10:48:46 +0000109 layoutInflater.inflate(contentLayoutRes, springLayout, true);
Steven Ng391404f2021-02-17 15:58:23 +0000110
Steven Ng167f81b2021-02-23 10:48:46 +0000111 RecyclerViewFastScroller fastScroller = findViewById(R.id.fast_scroller);
Steven Ng391404f2021-02-17 15:58:23 +0000112 if (mHasWorkProfile) {
113 mViewPager = findViewById(R.id.widgets_view_pager);
Steven Ng391404f2021-02-17 15:58:23 +0000114 mViewPager.initParentViews(this);
115 mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
116 mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.PRIMARY);
Steven Ng167f81b2021-02-23 10:48:46 +0000117 mTabsView = findViewById(R.id.tabs);
Steven Ng391404f2021-02-17 15:58:23 +0000118 findViewById(R.id.tab_personal)
119 .setOnClickListener((View view) -> mViewPager.snapToPage(0));
120 findViewById(R.id.tab_work)
121 .setOnClickListener((View view) -> mViewPager.snapToPage(1));
Steven Ng167f81b2021-02-23 10:48:46 +0000122 fastScroller.setIsRecyclerViewFirstChildInParent(false);
Steven Ng391404f2021-02-17 15:58:23 +0000123 springLayout.addSpringView(R.id.primary_widgets_list_view);
124 springLayout.addSpringView(R.id.work_widgets_list_view);
125 } else {
126 mViewPager = null;
127 springLayout.addSpringView(R.id.primary_widgets_list_view);
128 }
129
Steven Ng167f81b2021-02-23 10:48:46 +0000130 layoutInflater.inflate(R.layout.widgets_full_sheet_search_and_recommendations, springLayout,
131 true);
132 springLayout.addSpringView(R.id.search_and_recommendations_container);
133
134 mSearchAndRecommendationViewHolder = new SearchAndRecommendationViewHolder(
135 findViewById(R.id.search_and_recommendations_container));
136 mSearchAndRecommendationsScrollController = new SearchAndRecommendationsScrollController(
137 mHasWorkProfile,
138 mSearchAndRecommendationViewHolder,
139 findViewById(R.id.primary_widgets_list_view),
140 mHasWorkProfile ? findViewById(R.id.work_widgets_list_view) : null,
141 mTabsView,
142 mViewPager);
143 fastScroller.setOnFastScrollChangeListener(mSearchAndRecommendationsScrollController);
144
Steven Ngd73d6e52021-03-09 22:44:04 +0000145 mNoWidgetsView = findViewById(R.id.no_widgets_text);
146
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700147 onWidgetsBound();
148 }
149
Steven Ng391404f2021-02-17 15:58:23 +0000150 @Override
151 public void onActivePageChanged(int currentActivePage) {
Steven Ngd73d6e52021-03-09 22:44:04 +0000152 AdapterHolder currentAdapterHolder = mAdapters.get(currentActivePage);
153 WidgetsRecyclerView currentRecyclerView = currentAdapterHolder.mWidgetsRecyclerView;
Steven Ng7f7b2f72021-03-03 14:51:36 +0000154 currentRecyclerView.bindFastScrollbar();
155 mSearchAndRecommendationsScrollController.setCurrentRecyclerView(currentRecyclerView);
Steven Ng167f81b2021-02-23 10:48:46 +0000156
Steven Ngd73d6e52021-03-09 22:44:04 +0000157 updateNoWidgetsView(currentAdapterHolder);
158
Steven Ng167f81b2021-02-23 10:48:46 +0000159 reset();
160 }
161
Steven Ngd73d6e52021-03-09 22:44:04 +0000162 private void updateNoWidgetsView(AdapterHolder adapterHolder) {
163 boolean isWidgetAvailable = adapterHolder.mWidgetsListAdapter.getItemCount() > 0;
164 adapterHolder.mWidgetsRecyclerView.setVisibility(isWidgetAvailable ? VISIBLE : GONE);
165
166 // Always resets the text in case this is updated by search.
167 mNoWidgetsView.setText(R.string.no_widgets_available);
168 mNoWidgetsView.setVisibility(isWidgetAvailable ? GONE : VISIBLE);
169 }
170
Steven Ng167f81b2021-02-23 10:48:46 +0000171 private void reset() {
172 mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView.scrollToTop();
173 if (mHasWorkProfile) {
174 mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView.scrollToTop();
175 }
Steven Ng7f7b2f72021-03-03 14:51:36 +0000176 mSearchAndRecommendationsScrollController.reset();
Steven Ng391404f2021-02-17 15:58:23 +0000177 }
178
Sunny Goyal8b37c572020-03-31 12:12:14 -0700179 @VisibleForTesting
180 public WidgetsRecyclerView getRecyclerView() {
Steven Ng391404f2021-02-17 15:58:23 +0000181 if (!mHasWorkProfile || mViewPager.getCurrentPage() == AdapterHolder.PRIMARY) {
182 return mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
183 }
184 return mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView;
Sunny Goyal8b37c572020-03-31 12:12:14 -0700185 }
186
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700187 @Override
Sunny Goyalde753212018-05-15 13:55:57 -0700188 protected Pair<View, String> getAccessibilityTarget() {
Steven Ng391404f2021-02-17 15:58:23 +0000189 return Pair.create(getRecyclerView(), getContext().getString(
Sunny Goyalde753212018-05-15 13:55:57 -0700190 mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
191 }
192
193 @Override
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700194 protected void onAttachedToWindow() {
195 super.onAttachedToWindow();
196 mLauncher.getAppWidgetHost().addProviderChangeListener(this);
197 notifyWidgetProvidersChanged();
198 }
199
200 @Override
201 protected void onDetachedFromWindow() {
202 super.onDetachedFromWindow();
203 mLauncher.getAppWidgetHost().removeProviderChangeListener(this);
204 }
205
206 @Override
207 public void setInsets(Rect insets) {
208 mInsets.set(insets);
209
Steven Ng391404f2021-02-17 15:58:23 +0000210 setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, insets.bottom);
211 if (mHasWorkProfile) {
212 setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
213 }
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700214 if (insets.bottom > 0) {
215 setupNavBarColor();
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800216 } else {
217 clearNavBarColor();
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700218 }
Sunny Goyal3661bfa2018-03-01 16:29:15 -0800219
220 ((TopRoundedCornerView) mContent).setNavBarScrimHeight(mInsets.bottom);
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700221 requestLayout();
222 }
223
Steven Ng391404f2021-02-17 15:58:23 +0000224 private void setBottomPadding(RecyclerView recyclerView, int bottomPadding) {
225 recyclerView.setPadding(
226 recyclerView.getPaddingLeft(),
227 recyclerView.getPaddingTop(),
228 recyclerView.getPaddingRight(),
229 bottomPadding);
230 }
231
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700232 @Override
233 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Steven Nge8d92342021-02-19 21:29:18 +0000234 DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700235 int widthUsed;
236 if (mInsets.bottom > 0) {
Sunny Goyal786940a2020-06-02 02:31:31 -0700237 widthUsed = mInsets.left + mInsets.right;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700238 } else {
Steven Nge8d92342021-02-19 21:29:18 +0000239 Rect padding = deviceProfile.workspacePadding;
Sunny Goyal07b69292018-01-08 14:19:34 -0800240 widthUsed = Math.max(padding.left + padding.right,
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700241 2 * (mInsets.left + mInsets.right));
242 }
243
Steven Nge8d92342021-02-19 21:29:18 +0000244 int heightUsed = mInsets.top + deviceProfile.edgeMarginPx;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700245 measureChildWithMargins(mContent, widthMeasureSpec,
246 widthUsed, heightMeasureSpec, heightUsed);
Sunny Goyal6639a5d2018-02-28 15:09:36 -0800247 setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
248 MeasureSpec.getSize(heightMeasureSpec));
Steven Nge8d92342021-02-19 21:29:18 +0000249
Steven Ng11773f42021-02-25 22:54:37 +0000250 int paddingPx = 2 * getResources().getDimensionPixelOffset(
251 R.dimen.widget_cell_horizontal_padding);
252 int maxSpansPerRow = getMeasuredWidth() / (deviceProfile.cellWidthPx + paddingPx);
Steven Nge8d92342021-02-19 21:29:18 +0000253 mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.setMaxHorizontalSpansPerRow(
254 maxSpansPerRow);
255 if (mHasWorkProfile) {
256 mAdapters.get(AdapterHolder.WORK).mWidgetsListAdapter.setMaxHorizontalSpansPerRow(
257 maxSpansPerRow);
258 }
Steven Ng7f7b2f72021-03-03 14:51:36 +0000259
260 if (mInitialTabsHeight == 0 && mTabsView != null) {
261 mInitialTabsHeight = measureHeightWithVerticalMargins(mTabsView);
262 }
263
264 mSearchAndRecommendationsScrollController.updateMarginAndPadding();
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700265 }
266
267 @Override
268 protected void onLayout(boolean changed, int l, int t, int r, int b) {
269 int width = r - l;
270 int height = b - t;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700271
272 // Content is laid out as center bottom aligned
273 int contentWidth = mContent.getMeasuredWidth();
Sunny Goyal786940a2020-06-02 02:31:31 -0700274 int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700275 mContent.layout(contentLeft, height - mContent.getMeasuredHeight(),
276 contentLeft + contentWidth, height);
277
278 setTranslationShift(mTranslationShift);
279 }
280
281 @Override
282 public void notifyWidgetProvidersChanged() {
283 mLauncher.refreshAndBindWidgetsForPackageUser(null);
284 }
285
286 @Override
Sunny Goyal202ae0b2019-02-04 16:26:42 -0800287 public void onWidgetsBound() {
Steven Ng391404f2021-02-17 15:58:23 +0000288 List<WidgetsListBaseEntry> allWidgets = mLauncher.getPopupDataProvider().getAllWidgets();
289
290 AdapterHolder primaryUserAdapterHolder = mAdapters.get(AdapterHolder.PRIMARY);
291 primaryUserAdapterHolder.setup(findViewById(R.id.primary_widgets_list_view));
292 primaryUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
Steven Ngd73d6e52021-03-09 22:44:04 +0000293 updateNoWidgetsView(primaryUserAdapterHolder);
294
Steven Ng391404f2021-02-17 15:58:23 +0000295 if (mHasWorkProfile) {
296 AdapterHolder workUserAdapterHolder = mAdapters.get(AdapterHolder.WORK);
297 workUserAdapterHolder.setup(findViewById(R.id.work_widgets_list_view));
298 workUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
299 onActivePageChanged(mViewPager.getCurrentPage());
300 }
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700301 }
302
303 private void open(boolean animate) {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700304 if (animate) {
Sunny Goyaldb6cdb02018-07-13 11:03:04 -0700305 if (getPopupContainer().getInsets().bottom > 0) {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700306 mContent.setAlpha(0);
307 setTranslationShift(VERTICAL_START_POSITION);
308 }
309 mOpenCloseAnimator.setValues(
310 PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
311 mOpenCloseAnimator
312 .setDuration(DEFAULT_OPEN_DURATION)
313 .setInterpolator(AnimationUtils.loadInterpolator(
314 getContext(), android.R.interpolator.linear_out_slow_in));
315 mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
316 @Override
317 public void onAnimationEnd(Animator animation) {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700318 mOpenCloseAnimator.removeListener(this);
319 }
320 });
Sunny Goyal6639a5d2018-02-28 15:09:36 -0800321 post(() -> {
Sunny Goyal6639a5d2018-02-28 15:09:36 -0800322 mOpenCloseAnimator.start();
323 mContent.animate().alpha(1).setDuration(FADE_IN_DURATION);
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700324 });
325 } else {
326 setTranslationShift(TRANSLATION_SHIFT_OPENED);
Sunny Goyalde753212018-05-15 13:55:57 -0700327 post(this::announceAccessibilityChanges);
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700328 }
329 }
330
331 @Override
332 protected void handleClose(boolean animate) {
333 handleClose(animate, DEFAULT_OPEN_DURATION);
334 }
335
336 @Override
337 protected boolean isOfType(int type) {
338 return (type & TYPE_WIDGETS_FULL_SHEET) != 0;
339 }
340
341 @Override
342 public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
343 // Disable swipe down when recycler view is scrolling
344 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
345 mNoIntercept = false;
Steven Ng391404f2021-02-17 15:58:23 +0000346 RecyclerViewFastScroller scroller = getRecyclerView().getScrollbar();
Steven Ng2f5648a2021-02-08 17:18:25 +0000347 if (scroller.getThumbOffsetY() >= 0
348 && getPopupContainer().isEventOverView(scroller, ev)) {
Sunny Goyal3661bfa2018-03-01 16:29:15 -0800349 mNoIntercept = true;
Sunny Goyaldb6cdb02018-07-13 11:03:04 -0700350 } else if (getPopupContainer().isEventOverView(mContent, ev)) {
Steven Ng391404f2021-02-17 15:58:23 +0000351 mNoIntercept = !getRecyclerView().shouldContainerScroll(ev, getPopupContainer());
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700352 }
353 }
354 return super.onControllerInterceptTouchEvent(ev);
355 }
356
Steven Ng2f5648a2021-02-08 17:18:25 +0000357 /** Shows the {@link WidgetsFullSheet} on the launcher. */
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700358 public static WidgetsFullSheet show(Launcher launcher, boolean animate) {
359 WidgetsFullSheet sheet = (WidgetsFullSheet) launcher.getLayoutInflater()
360 .inflate(R.layout.widgets_full_sheet, launcher.getDragLayer(), false);
Sunny Goyal1642f712018-09-18 11:40:35 -0700361 sheet.attachToContainer();
Sunny Goyalde753212018-05-15 13:55:57 -0700362 sheet.mIsOpen = true;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700363 sheet.open(animate);
364 return sheet;
365 }
Sunny Goyalaeb16432017-10-16 11:46:41 -0700366
Steven Ng2f5648a2021-02-08 17:18:25 +0000367 /** Gets the {@link WidgetsRecyclerView} which shows all widgets in {@link WidgetsFullSheet}. */
Vadim Tryshev2ce6a132018-06-18 19:14:44 -0700368 @VisibleForTesting
369 public static WidgetsRecyclerView getWidgetsView(Launcher launcher) {
Steven Ng391404f2021-02-17 15:58:23 +0000370 return launcher.findViewById(R.id.primary_widgets_list_view);
Vadim Tryshev2ce6a132018-06-18 19:14:44 -0700371 }
372
Sunny Goyalaeb16432017-10-16 11:46:41 -0700373 @Override
Sunny Goyalf3ac7032020-03-13 13:01:33 -0700374 public void addHintCloseAnim(
375 float distanceToMove, Interpolator interpolator, PendingAnimation target) {
Steven Ng391404f2021-02-17 15:58:23 +0000376 target.setFloat(getRecyclerView(), VIEW_TRANSLATE_Y, -distanceToMove, interpolator);
377 target.setViewAlpha(getRecyclerView(), 0.5f, interpolator);
Tony Wickham9791bd12019-04-05 13:52:35 -0700378 }
vadimt9f48a8e2019-12-11 11:52:37 -0800379
380 @Override
381 protected void onCloseComplete() {
382 super.onCloseComplete();
383 AccessibilityManagerCompat.sendStateEventToTest(getContext(), NORMAL_STATE_ORDINAL);
384 }
Steven Ng391404f2021-02-17 15:58:23 +0000385
Steven Ng167f81b2021-02-23 10:48:46 +0000386 @Override
387 public int getHeaderViewHeight() {
Steven Ng53d13642021-03-10 22:40:55 +0000388 return measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mCollapseHandle)
389 + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mHeaderTitle)
390 + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mSearchBar);
Steven Ng7f7b2f72021-03-03 14:51:36 +0000391 }
392
393 /** private the height, in pixel, + the vertical margins of a given view. */
394 private static int measureHeightWithVerticalMargins(View view) {
Steven Ng53d13642021-03-10 22:40:55 +0000395 if (view.getVisibility() != VISIBLE) {
396 return 0;
397 }
Steven Ng7f7b2f72021-03-03 14:51:36 +0000398 MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
399 return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
400 + marginLayoutParams.topMargin;
Steven Ng167f81b2021-02-23 10:48:46 +0000401 }
402
Steven Ng391404f2021-02-17 15:58:23 +0000403 /** A holder class for holding adapters & their corresponding recycler view. */
404 private final class AdapterHolder {
405 static final int PRIMARY = 0;
406 static final int WORK = 1;
407
408 private final int mAdapterType;
409 private final WidgetsListAdapter mWidgetsListAdapter;
410
411 private WidgetsRecyclerView mWidgetsRecyclerView;
412
413 AdapterHolder(int adapterType) {
414 mAdapterType = adapterType;
415
416 Context context = getContext();
417 LauncherAppState apps = LauncherAppState.getInstance(context);
418 mWidgetsListAdapter = new WidgetsListAdapter(
419 context,
420 LayoutInflater.from(context),
421 apps.getWidgetCache(),
422 apps.getIconCache(),
423 /* iconClickListener= */ WidgetsFullSheet.this,
424 /* iconLongClickListener= */ WidgetsFullSheet.this);
425 mWidgetsListAdapter.setFilter(
426 mAdapterType == PRIMARY ? mPrimaryWidgetsFilter : mWorkWidgetsFilter);
427 }
428
429 void setup(WidgetsRecyclerView recyclerView) {
430 mWidgetsRecyclerView = recyclerView;
431 mWidgetsRecyclerView.setAdapter(mWidgetsListAdapter);
Steven Ng167f81b2021-02-23 10:48:46 +0000432 mWidgetsRecyclerView.setHeaderViewDimensionsProvider(WidgetsFullSheet.this);
Steven Ng391404f2021-02-17 15:58:23 +0000433 mWidgetsRecyclerView.setEdgeEffectFactory(
434 ((TopRoundedCornerView) mContent).createEdgeEffectFactory());
435 mWidgetsListAdapter.setApplyBitmapDeferred(false, mWidgetsRecyclerView);
436 }
437 }
Steven Ng167f81b2021-02-23 10:48:46 +0000438
439 final class SearchAndRecommendationViewHolder {
440 final View mContainer;
441 final View mCollapseHandle;
442 final EditText mSearchBar;
443 final TextView mHeaderTitle;
444
445 SearchAndRecommendationViewHolder(View searchAndRecommendationContainer) {
446 mContainer = searchAndRecommendationContainer;
447 mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
448 mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
449 mHeaderTitle = mContainer.findViewById(R.id.title);
450 }
451 }
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700452}