Introduce feature education for AllApps Search
Preview: https://drive.google.com/file/d/1eXf3K6kFh0bHcYlpwW_voSRjY9RQalJN/view?usp=sharing&resourcekey=0-IABjrtXM5JhHvSf-7yc4tg Edu can be dismissed permanently by pressing "Got it" button or typing. Swiping down defers edu until next visit to all apps - Move fallback search to quickstep Bug: 178100472 Test: Manual Change-Id: I920aab366330758e81f8b9fa62736abf82fe5cac
This commit is contained in:
parent
867b62a2d0
commit
062a8fd979
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.search.FallbackSearchInputView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="start|center_vertical"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:imeOptions="actionSearch|flagNoExtractUi"
|
||||
android:maxLines="1"
|
||||
android:privateImeOptions="bc_search"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textColorHint="?android:attr/textColorTertiary"
|
||||
android:textSize="16sp" />
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2008 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.search.DeviceSearchEdu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/search_box_wrapper"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<include
|
||||
layout="@layout/fallback_search_input"
|
||||
android:id="@+id/mock_search_box" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/edu_wrapper"
|
||||
android:padding="24dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<TextView
|
||||
style="@style/TextHeadline"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:textSize="24sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search_edu_primary" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextHeadline"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search_edu_secondary" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/dismiss_edu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginTop="@dimen/dynamic_grid_edge_margin"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/search_edu_dismiss" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.launcher3.search.DeviceSearchEdu>
|
|
@ -93,6 +93,15 @@
|
|||
<!-- content description for hotseat items -->
|
||||
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
|
||||
|
||||
<!-- primary educational text shown for first time search users -->
|
||||
<string name="search_edu_primary">Search your phone for apps, people, settings and more!</string>
|
||||
<!-- secondary educational text shown for first time search users -->
|
||||
<string name="search_edu_secondary">Tap keyboard search button to launch the first search
|
||||
result.</string>
|
||||
|
||||
<!-- Dismiss button string for search education view -->
|
||||
<string name="search_edu_dismiss">Got it.</string>
|
||||
|
||||
<!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
|
||||
<string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>
|
||||
<!-- Subtitle shown during interactive parts of Back gesture tutorial for right edge. [CHAR LIMIT=60] -->
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.search;
|
||||
|
||||
import static com.android.launcher3.util.OnboardingPrefs.SEARCH_EDU_SEEN;
|
||||
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.AbstractSlideInView;
|
||||
|
||||
/**
|
||||
* Feature education for on-device Search. Shown the first time user opens AllApps Search
|
||||
*/
|
||||
public class DeviceSearchEdu extends AbstractSlideInView implements
|
||||
StateManager.StateListener<LauncherState>, TextWatcher, Insettable,
|
||||
TextView.OnEditorActionListener {
|
||||
|
||||
private static final long ANIMATION_DURATION = 350;
|
||||
private static final int ANIMATION_CONTENT_TRANSLATION = 200;
|
||||
|
||||
private EditText mEduInput;
|
||||
|
||||
private View mInputWrapper;
|
||||
private EditText mSearchInput;
|
||||
|
||||
private boolean mSwitchFocusOnDismiss;
|
||||
|
||||
|
||||
public DeviceSearchEdu(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public DeviceSearchEdu(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DeviceSearchEdu(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
private void close(boolean animate, boolean markAsSeen) {
|
||||
handleClose(animate);
|
||||
if (markAsSeen) {
|
||||
mLauncher.getOnboardingPrefs().markChecked(SEARCH_EDU_SEEN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClose(boolean animate) {
|
||||
handleClose(animate, ANIMATION_DURATION);
|
||||
mLauncher.getStateManager().removeStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOfType(int type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mSearchInput = mLauncher.getAppsView().getSearchUiManager().getEditText();
|
||||
mInputWrapper = findViewById(R.id.search_box_wrapper);
|
||||
mContent = findViewById(R.id.edu_wrapper);
|
||||
|
||||
mEduInput = findViewById(R.id.mock_search_box);
|
||||
mEduInput.setHint(R.string.all_apps_on_device_search_bar_hint);
|
||||
mEduInput.addTextChangedListener(this);
|
||||
if (mSearchInput != null) {
|
||||
mEduInput.getLayoutParams().height = mSearchInput.getHeight();
|
||||
mEduInput.setOnEditorActionListener(this);
|
||||
} else {
|
||||
mEduInput.setVisibility(INVISIBLE);
|
||||
}
|
||||
|
||||
findViewById(R.id.dismiss_edu).setOnClickListener((view) -> {
|
||||
mSwitchFocusOnDismiss = true;
|
||||
close(true, true);
|
||||
});
|
||||
}
|
||||
|
||||
private void showInternal() {
|
||||
mLauncher.getStateManager().addStateListener(this);
|
||||
AbstractFloatingView.closeAllOpenViews(mLauncher);
|
||||
attachToContainer();
|
||||
if (mSearchInput != null) {
|
||||
Rect r = mLauncher.getViewBounds(mSearchInput);
|
||||
mEduInput.requestFocus();
|
||||
InputMethodManager imm = mLauncher.getSystemService(InputMethodManager.class);
|
||||
imm.showSoftInput(mEduInput, InputMethodManager.SHOW_IMPLICIT);
|
||||
((LayoutParams) mInputWrapper.getLayoutParams()).setMargins(0, r.top, 0, 0);
|
||||
}
|
||||
animateOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrimColor(Context context) {
|
||||
return ColorUtils.setAlphaComponent(Themes.getAttrColor(context, R.attr.allAppsScrimColor),
|
||||
230);
|
||||
}
|
||||
|
||||
protected void setTranslationShift(float translationShift) {
|
||||
mTranslationShift = translationShift;
|
||||
mContent.setAlpha(getBoxedProgress(1 - mTranslationShift, .25f, 1));
|
||||
mContent.setTranslationY(ANIMATION_CONTENT_TRANSLATION * translationShift);
|
||||
if (mColorScrim != null) {
|
||||
mColorScrim.setAlpha(getBoxedProgress(1 - mTranslationShift, 0, .75f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given input [0-1], returns progress within bounds [min,max] allowing for staged animations
|
||||
*/
|
||||
private float getBoxedProgress(float input, float min, float max) {
|
||||
if (input < min) return 0;
|
||||
if (input > max) return 1;
|
||||
return (input - min) / (max - min);
|
||||
}
|
||||
|
||||
private void animateOpen() {
|
||||
if (mIsOpen || mOpenCloseAnimator.isRunning()) {
|
||||
return;
|
||||
}
|
||||
mIsOpen = true;
|
||||
mOpenCloseAnimator.setValues(
|
||||
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
|
||||
mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mOpenCloseAnimator.setDuration(ANIMATION_DURATION);
|
||||
mOpenCloseAnimator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show On-device search education view.
|
||||
*/
|
||||
public static void show(Launcher launcher) {
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(launcher);
|
||||
((DeviceSearchEdu) layoutInflater.inflate(
|
||||
R.layout.search_edu_view, launcher.getDragLayer(),
|
||||
false)).showInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionStart(LauncherState toState) {
|
||||
close(true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCloseComplete() {
|
||||
super.onCloseComplete();
|
||||
if (mSearchInput != null && mSwitchFocusOnDismiss) {
|
||||
mSearchInput.requestFocus();
|
||||
mSearchInput.setSelection(mSearchInput.getText().length());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
//Does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
//Does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
if (mSearchInput != null) {
|
||||
mSearchInput.setText(charSequence.toString());
|
||||
mSwitchFocusOnDismiss = true;
|
||||
close(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsets(Rect insets) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
|
||||
mSearchInput.onEditorAction(i);
|
||||
close(true, true);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.search;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.launcher3.ExtendedEditText;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
|
||||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.allapps.AlphabeticalAppsList;
|
||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
|
||||
import com.android.launcher3.allapps.search.SearchAlgorithm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A search view shown in all apps for on device search
|
||||
*/
|
||||
public class FallbackSearchInputView extends ExtendedEditText
|
||||
implements AllAppsSearchBarController.Callbacks, AllAppsStore.OnUpdateListener {
|
||||
|
||||
private final AllAppsSearchBarController mSearchBarController;
|
||||
|
||||
private AlphabeticalAppsList mApps;
|
||||
private Runnable mOnResultsChanged;
|
||||
private AllAppsContainerView mAppsView;
|
||||
|
||||
public FallbackSearchInputView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public FallbackSearchInputView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public FallbackSearchInputView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mSearchBarController = new AllAppsSearchBarController();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
Launcher.getLauncher(getContext()).getAppsView().getAppsStore().addUpdateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
Launcher.getLauncher(getContext()).getAppsView().getAppsStore().removeUpdateListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes SearchInput
|
||||
*/
|
||||
public void initialize(AllAppsContainerView appsView, SearchAlgorithm algo, Runnable changed) {
|
||||
mOnResultsChanged = changed;
|
||||
mApps = appsView.getApps();
|
||||
mAppsView = appsView;
|
||||
mSearchBarController.initialize(algo, this, Launcher.getLauncher(getContext()), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchResult(String query, ArrayList<AdapterItem> items) {
|
||||
if (mApps != null && getParent() != null) {
|
||||
mApps.setSearchResults(items);
|
||||
notifyResultChanged();
|
||||
collapseAppsViewHeader(true);
|
||||
mAppsView.setLastSearchQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppendSearchResult(String query, ArrayList<AdapterItem> items) {
|
||||
if (mApps != null && getParent() != null) {
|
||||
mApps.appendSearchResults(items);
|
||||
notifyResultChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSearchResult() {
|
||||
if (getParent() != null && mApps != null) {
|
||||
mApps.setSearchResults(null);
|
||||
notifyResultChanged();
|
||||
collapseAppsViewHeader(false);
|
||||
mAppsView.onClearSearchResult();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppsUpdated() {
|
||||
mSearchBarController.refreshSearchResult();
|
||||
}
|
||||
|
||||
private void collapseAppsViewHeader(boolean collapse) {
|
||||
FloatingHeaderView header = mAppsView.getFloatingHeaderView();
|
||||
if (header != null) {
|
||||
header.setCollapsed(collapse);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyResultChanged() {
|
||||
if (mOnResultsChanged != null) {
|
||||
mOnResultsChanged.run();
|
||||
}
|
||||
mAppsView.onSearchResultsChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
|
||||
// TODO: Consider animating the state transition here
|
||||
if (focused) {
|
||||
// Getting focus will open the keyboard. Go to the all-apps state, so that the input
|
||||
// box is at the top and there is enough space below to show search results.
|
||||
Launcher.getLauncher(getContext()).getStateManager().goToState(ALL_APPS, false);
|
||||
}
|
||||
super.onFocusChanged(focused, direction, previouslyFocusedRect);
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ import com.android.launcher3.LauncherState;
|
|||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
|
||||
import com.android.launcher3.search.DeviceSearchEdu;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
|
@ -41,6 +42,7 @@ import com.android.quickstep.views.AllAppsEduView;
|
|||
*/
|
||||
public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher> {
|
||||
|
||||
|
||||
public QuickstepOnboardingPrefs(QuickstepLauncher launcher, SharedPreferences sharedPrefs) {
|
||||
super(launcher, sharedPrefs);
|
||||
|
||||
|
@ -131,5 +133,18 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher>
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && !getBoolean(SEARCH_EDU_SEEN)) {
|
||||
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||
@Override
|
||||
public void onStateTransitionStart(LauncherState toState) {
|
||||
if (toState == ALL_APPS) {
|
||||
mLauncher.getAllAppsController().getInsetController().setSearchEduRunnable(
|
||||
() -> DeviceSearchEdu.show(launcher));
|
||||
stateManager.removeStateListener(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ public class AllAppsInsetTransitionController {
|
|||
private WindowInsetsAnimationController mAnimationController;
|
||||
private WindowInsetsAnimationControlListener mCurrentRequest;
|
||||
|
||||
private Runnable mSearchEduRunnable;
|
||||
|
||||
private float mAllAppsHeight;
|
||||
|
||||
private int mDownInsetBottom;
|
||||
|
@ -55,12 +57,28 @@ public class AllAppsInsetTransitionController {
|
|||
private float mDown, mCurrent;
|
||||
private View mApps;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public boolean showSearchEduIfNecessary() {
|
||||
if (mSearchEduRunnable == null) {
|
||||
return false;
|
||||
}
|
||||
mSearchEduRunnable.run();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSearchEduRunnable(Runnable eduRunnable) {
|
||||
mSearchEduRunnable = eduRunnable;
|
||||
}
|
||||
|
||||
// Only purpose of these states is to keep track of fast fling transition
|
||||
enum State {
|
||||
RESET, DRAG_START_BOTTOM, DRAG_START_BOTTOM_IME_CANCELLED,
|
||||
FLING_END_TOP, FLING_END_TOP_IME_CANCELLED,
|
||||
DRAG_START_TOP, FLING_END_BOTTOM
|
||||
}
|
||||
|
||||
private State mState;
|
||||
|
||||
public AllAppsInsetTransitionController(float allAppsHeight, View appsView) {
|
||||
|
@ -77,7 +95,7 @@ public class AllAppsInsetTransitionController {
|
|||
boolean imeVisible = insets.isVisible(WindowInsets.Type.ime());
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "\nhide imeVisible=" + imeVisible);
|
||||
Log.d(TAG, "\nhide imeVisible=" + imeVisible);
|
||||
}
|
||||
if (insets.isVisible(WindowInsets.Type.ime())) {
|
||||
mApps.getWindowInsetsController().hide(WindowInsets.Type.ime());
|
||||
|
@ -107,7 +125,7 @@ public class AllAppsInsetTransitionController {
|
|||
// mShownAtDown = mApps.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "\nonDragStart progress=" + progress
|
||||
Log.d(TAG, "\nonDragStart progress=" + progress
|
||||
+ " mDownInsets=" + mDownInsetBottom
|
||||
+ " mShownAtDown=" + mShownAtDown);
|
||||
}
|
||||
|
@ -123,7 +141,7 @@ public class AllAppsInsetTransitionController {
|
|||
}
|
||||
if (controller != null) {
|
||||
if (mCurrentRequest == this && !handleFinishOnFling(controller)) {
|
||||
mAnimationController = controller;
|
||||
mAnimationController = controller;
|
||||
} else {
|
||||
controller.finish(false /* just don't show */);
|
||||
}
|
||||
|
|
|
@ -270,11 +270,10 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
|||
if (Float.compare(mProgress, 0f) == 0) {
|
||||
mLauncher.getLiveSearchManager().start();
|
||||
EditText editText = mAppsView.getSearchUiManager().getEditText();
|
||||
if (editText != null) {
|
||||
if (editText != null && !mInsetController.showSearchEduIfNecessary()) {
|
||||
editText.requestFocus();
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mLauncher.getLiveSearchManager().stop();
|
||||
}
|
||||
// TODO: should make the controller hide synchronously
|
||||
|
|
|
@ -36,13 +36,15 @@ public class OnboardingPrefs<T extends Launcher> {
|
|||
public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
|
||||
public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
|
||||
public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
|
||||
public static final String SEARCH_EDU_SEEN = "launcher.search_edu";
|
||||
|
||||
/**
|
||||
* Events that either have happened or have not (booleans).
|
||||
*/
|
||||
@StringDef(value = {
|
||||
HOME_BOUNCE_SEEN,
|
||||
HOTSEAT_LONGPRESS_TIP_SEEN
|
||||
HOTSEAT_LONGPRESS_TIP_SEEN,
|
||||
SEARCH_EDU_SEEN
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface EventBoolKey {}
|
||||
|
|
|
@ -64,7 +64,7 @@ public abstract class AbstractSlideInView extends AbstractFloatingView
|
|||
protected final ObjectAnimator mOpenCloseAnimator;
|
||||
|
||||
protected View mContent;
|
||||
private final View mColorScrim;
|
||||
protected final View mColorScrim;
|
||||
protected Interpolator mScrollInterpolator;
|
||||
|
||||
// range [0, 1], 0=> completely open, 1=> completely closed
|
||||
|
@ -216,7 +216,6 @@ public abstract class AbstractSlideInView extends AbstractFloatingView
|
|||
return mLauncher.getDragLayer();
|
||||
}
|
||||
|
||||
|
||||
protected static View createColorScrim(Context context, int bgColor) {
|
||||
View view = new View(context);
|
||||
view.forceHasOverlappingRendering(false);
|
||||
|
|
Loading…
Reference in New Issue