Moving apps search related logic into a custom layout file
This will allow derivative projects to easily change the search behavior by simply overriding the xml file Bug: 37616877 Change-Id: Ib8d6a2dab06819a52611e9a3d97c70c5a49bbf97
This commit is contained in:
parent
b73fa5d7a4
commit
161f96bc77
|
@ -64,33 +64,9 @@
|
|||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/search_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_search_bar_height"
|
||||
android:layout_gravity="center|top"
|
||||
android:gravity="center|bottom"
|
||||
android:orientation="horizontal"
|
||||
android:saveEnabled="false">
|
||||
|
||||
<com.android.launcher3.ExtendedEditText
|
||||
android:id="@+id/search_box_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_search_bar_field_height"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_gravity="bottom"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:imeOptions="actionSearch|flagNoExtractUi"
|
||||
android:inputType="text|textNoSuggestions|textCapWords"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:hint="@string/all_apps_search_bar_hint"
|
||||
android:textColorHint="@drawable/all_apps_search_hint"
|
||||
android:textSize="16sp" />
|
||||
</FrameLayout>
|
||||
<include
|
||||
layout="@layout/all_apps_search_container"
|
||||
android:id="@+id/search_container" />
|
||||
|
||||
</com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
|
||||
<View
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 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.allapps.search.AppsSearchContainerLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_search_bar_height"
|
||||
android:layout_gravity="center|top"
|
||||
android:gravity="center|bottom"
|
||||
android:id="@+id/search_container"
|
||||
android:saveEnabled="false">
|
||||
|
||||
<com.android.launcher3.ExtendedEditText
|
||||
android:id="@+id/search_box_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_search_bar_field_height"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_gravity="bottom"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:imeOptions="actionSearch|flagNoExtractUi"
|
||||
android:inputType="text|textNoSuggestions|textCapWords"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:hint="@string/all_apps_search_bar_hint"
|
||||
android:textColorHint="@drawable/all_apps_search_hint"
|
||||
android:textSize="16sp" />
|
||||
</com.android.launcher3.allapps.search.AppsSearchContainerLayout>
|
|
@ -51,7 +51,6 @@
|
|||
<!-- Fast scroller popup -->
|
||||
<TextView
|
||||
style="@style/FastScrollerPopup"
|
||||
android:layout_below="@+id/search_container"
|
||||
android:id="@+id/fast_scroller_popup"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
easily override the app name without providing all translations -->
|
||||
<string name="derived_app_name" translatable="false">@string/app_name</string>
|
||||
|
||||
<!-- String representing the intent for search on the apps market. To specify a query, add
|
||||
q=<query> to the data to the intent -->
|
||||
<string name="market_search_intent" translatable="false">market://search?c=apps</string>
|
||||
|
||||
<!-- Values for icon shape overrides. These should correspond to entries defined
|
||||
in icon_shape_override_paths_names -->
|
||||
<string-array name="icon_shape_override_paths_values">
|
||||
|
|
|
@ -82,10 +82,6 @@ public abstract class BaseRecyclerView extends RecyclerView
|
|||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mScrollbar.reattachThumbToScroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
|
|
@ -85,7 +85,6 @@ import com.android.launcher3.LauncherSettings.Favorites;
|
|||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.allapps.DefaultAppSearchController;
|
||||
import com.android.launcher3.anim.AnimationLayerSet;
|
||||
import com.android.launcher3.compat.AppWidgetManagerCompat;
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
|
@ -560,47 +559,6 @@ public class Launcher extends BaseActivity
|
|||
|
||||
public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
|
||||
mLauncherCallbacks = callbacks;
|
||||
mLauncherCallbacks.setLauncherSearchCallback(new Launcher.LauncherSearchCallbacks() {
|
||||
private boolean mWorkspaceImportanceStored = false;
|
||||
private boolean mHotseatImportanceStored = false;
|
||||
private int mWorkspaceImportanceForAccessibility =
|
||||
View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
|
||||
private int mHotseatImportanceForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
|
||||
|
||||
@Override
|
||||
public void onSearchOverlayOpened() {
|
||||
if (mWorkspaceImportanceStored || mHotseatImportanceStored) {
|
||||
return;
|
||||
}
|
||||
// The underlying workspace and hotseat are temporarily suppressed by the search
|
||||
// overlay. So they shouldn't be accessible.
|
||||
if (mWorkspace != null) {
|
||||
mWorkspaceImportanceForAccessibility =
|
||||
mWorkspace.getImportantForAccessibility();
|
||||
mWorkspace.setImportantForAccessibility(
|
||||
View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
||||
mWorkspaceImportanceStored = true;
|
||||
}
|
||||
if (mHotseat != null) {
|
||||
mHotseatImportanceForAccessibility = mHotseat.getImportantForAccessibility();
|
||||
mHotseat.setImportantForAccessibility(
|
||||
View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
||||
mHotseatImportanceStored = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchOverlayClosed() {
|
||||
if (mWorkspaceImportanceStored && mWorkspace != null) {
|
||||
mWorkspace.setImportantForAccessibility(mWorkspaceImportanceForAccessibility);
|
||||
}
|
||||
if (mHotseatImportanceStored && mHotseat != null) {
|
||||
mHotseat.setImportantForAccessibility(mHotseatImportanceForAccessibility);
|
||||
}
|
||||
mWorkspaceImportanceStored = false;
|
||||
mHotseatImportanceStored = false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1140,18 +1098,6 @@ public class Launcher extends BaseActivity
|
|||
public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
|
||||
}
|
||||
|
||||
public interface LauncherSearchCallbacks {
|
||||
/**
|
||||
* Called when the search overlay is shown.
|
||||
*/
|
||||
public void onSearchOverlayOpened();
|
||||
|
||||
/**
|
||||
* Called when the search overlay is dismissed.
|
||||
*/
|
||||
public void onSearchOverlayClosed();
|
||||
}
|
||||
|
||||
public interface LauncherOverlayCallbacks {
|
||||
public void onScrollChanged(float progress);
|
||||
}
|
||||
|
@ -1344,11 +1290,6 @@ public class Launcher extends BaseActivity
|
|||
// Setup Apps and Widgets
|
||||
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
|
||||
mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
|
||||
if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
|
||||
mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
|
||||
} else {
|
||||
mAppsView.setSearchBarController(new DefaultAppSearchController());
|
||||
}
|
||||
|
||||
// Setup the drag controller (drop targets have to be added in reverse order in priority)
|
||||
mDragController.setMoveTarget(mWorkspace);
|
||||
|
@ -1777,7 +1718,7 @@ public class Launcher extends BaseActivity
|
|||
|
||||
// Reset the apps view
|
||||
if (!alreadyOnHome && mAppsView != null) {
|
||||
mAppsView.scrollToTop();
|
||||
mAppsView.reset();
|
||||
}
|
||||
|
||||
// Reset the widgets view
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.os.Bundle;
|
|||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.allapps.AllAppsSearchBarController;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
@ -92,20 +91,11 @@ public interface LauncherCallbacks {
|
|||
*/
|
||||
boolean shouldMoveToDefaultScreenOnHomeIntent();
|
||||
boolean hasSettings();
|
||||
AllAppsSearchBarController getAllAppsSearchBarController();
|
||||
List<ComponentKey> getPredictedApps();
|
||||
int SEARCH_BAR_HEIGHT_NORMAL = 0, SEARCH_BAR_HEIGHT_TALL = 1;
|
||||
/** Must return one of {@link #SEARCH_BAR_HEIGHT_NORMAL} or {@link #SEARCH_BAR_HEIGHT_TALL} */
|
||||
int getSearchBarHeight();
|
||||
|
||||
/**
|
||||
* Sets the callbacks to allow reacting the actions of search overlays of the launcher.
|
||||
*
|
||||
* @param callbacks A set of callbacks to the Launcher, is actually a LauncherSearchCallback,
|
||||
* but for implementation purposes is passed around as an object.
|
||||
*/
|
||||
void setLauncherSearchCallback(Object callbacks);
|
||||
|
||||
boolean shouldShowDiscoveryBounce();
|
||||
|
||||
void onExtractedColorsChanged();
|
||||
|
|
|
@ -20,15 +20,9 @@ import android.graphics.Color;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Selection;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -42,7 +36,6 @@ import com.android.launcher3.DeleteDropTarget;
|
|||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.ExtendedEditText;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
|
@ -50,18 +43,14 @@ import com.android.launcher3.PromiseAppInfo;
|
|||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.discovery.AppDiscoveryItem;
|
||||
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.folder.Folder;
|
||||
import com.android.launcher3.graphics.TintedDrawableSpan;
|
||||
import com.android.launcher3.keyboard.FocusedItemDecorator;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -69,7 +58,7 @@ import java.util.Set;
|
|||
* The all apps view container.
|
||||
*/
|
||||
public class AllAppsContainerView extends BaseContainerView implements DragSource,
|
||||
View.OnLongClickListener, AllAppsSearchBarController.Callbacks, Insettable {
|
||||
View.OnLongClickListener, Insettable {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final AlphabeticalAppsList mApps;
|
||||
|
@ -77,12 +66,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
private final RecyclerView.LayoutManager mLayoutManager;
|
||||
|
||||
private AllAppsRecyclerView mAppsRecyclerView;
|
||||
private AllAppsSearchBarController mSearchBarController;
|
||||
|
||||
private SearchUiManager mSearchUiManager;
|
||||
private View mSearchContainer;
|
||||
private int mSearchContainerMinHeight;
|
||||
private ExtendedEditText mSearchInput;
|
||||
private HeaderElevationController mElevationController;
|
||||
|
||||
private SpannableStringBuilder mSearchQueryBuilder = null;
|
||||
|
||||
|
@ -106,8 +91,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
mApps.setAdapter(mAdapter);
|
||||
mLayoutManager = mAdapter.getLayoutManager();
|
||||
mSearchQueryBuilder = new SpannableStringBuilder();
|
||||
mSearchContainerMinHeight
|
||||
= getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
|
||||
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
}
|
||||
|
@ -149,7 +132,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
*/
|
||||
public void addApps(List<AppInfo> apps) {
|
||||
mApps.addApps(apps);
|
||||
mSearchBarController.refreshSearchResult();
|
||||
mSearchUiManager.refreshSearchResult();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +140,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
*/
|
||||
public void updateApps(List<AppInfo> apps) {
|
||||
mApps.updateApps(apps);
|
||||
mSearchBarController.refreshSearchResult();
|
||||
mSearchUiManager.refreshSearchResult();
|
||||
}
|
||||
|
||||
public void updatePromiseAppProgress(PromiseAppInfo app) {
|
||||
|
@ -176,34 +159,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
*/
|
||||
public void removeApps(List<AppInfo> apps) {
|
||||
mApps.removeApps(apps);
|
||||
mSearchBarController.refreshSearchResult();
|
||||
}
|
||||
|
||||
public void setSearchBarVisible(boolean visible) {
|
||||
if (visible) {
|
||||
mSearchBarController.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mSearchBarController.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the search bar that shows above the a-z list.
|
||||
*/
|
||||
public void setSearchBarController(AllAppsSearchBarController searchController) {
|
||||
if (mSearchBarController != null) {
|
||||
throw new RuntimeException("Expected search bar controller to only be set once");
|
||||
}
|
||||
mSearchBarController = searchController;
|
||||
mSearchBarController.initialize(mApps, mSearchInput, mLauncher, this);
|
||||
mAdapter.setSearchController(mSearchBarController);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls this list view to the top.
|
||||
*/
|
||||
public void scrollToTop() {
|
||||
mAppsRecyclerView.scrollToTop();
|
||||
mSearchUiManager.refreshSearchResult();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,9 +194,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
* Focuses the search field and begins an app search.
|
||||
*/
|
||||
public void startAppsSearch() {
|
||||
if (mSearchBarController != null) {
|
||||
mSearchBarController.focusSearchField();
|
||||
}
|
||||
mSearchUiManager.startAppsSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,9 +202,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
*/
|
||||
public void reset() {
|
||||
// Reset the search bar and base recycler view after transitioning home
|
||||
scrollToTop();
|
||||
mSearchBarController.reset();
|
||||
mAppsRecyclerView.reset();
|
||||
mAppsRecyclerView.scrollToTop();
|
||||
mSearchUiManager.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -268,28 +221,17 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
}
|
||||
});
|
||||
|
||||
mSearchContainer = findViewById(R.id.search_container);
|
||||
mSearchInput = (ExtendedEditText) findViewById(R.id.search_box_input);
|
||||
|
||||
// Update the hint to contain the icon.
|
||||
// Prefix the original hint with two spaces. The first space gets replaced by the icon
|
||||
// using span. The second space is used for a singe space character between the hint
|
||||
// and the icon.
|
||||
SpannableString spanned = new SpannableString(" " + mSearchInput.getHint());
|
||||
spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
|
||||
0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
|
||||
mSearchInput.setHint(spanned);
|
||||
|
||||
mElevationController = new HeaderElevationController(mSearchContainer);
|
||||
|
||||
// Load the all apps recycler view
|
||||
mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
|
||||
mAppsRecyclerView.setApps(mApps);
|
||||
mAppsRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mAppsRecyclerView.setAdapter(mAdapter);
|
||||
mAppsRecyclerView.setHasFixedSize(true);
|
||||
mAppsRecyclerView.addOnScrollListener(mElevationController);
|
||||
mAppsRecyclerView.setElevationController(mElevationController);
|
||||
|
||||
mSearchContainer = findViewById(R.id.search_container);
|
||||
mSearchUiManager = (SearchUiManager) mSearchContainer;
|
||||
mSearchUiManager.initialize(mApps, mAppsRecyclerView);
|
||||
|
||||
|
||||
FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mAppsRecyclerView);
|
||||
mAppsRecyclerView.addItemDecoration(focusedItemDecorator);
|
||||
|
@ -308,13 +250,12 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
return mAppsRecyclerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBoundsChanged(Rect newBounds) { }
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
// Update the number of items in the grid before we measure the view
|
||||
grid.updateAppsViewNumCols();
|
||||
|
||||
if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
|
||||
if (mNumAppsPerRow != grid.inv.numColumns ||
|
||||
mNumPredictedAppsPerRow != grid.inv.numColumns) {
|
||||
|
@ -325,22 +266,11 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
|
||||
mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
|
||||
}
|
||||
if (!grid.isVerticalBarLayout()) {
|
||||
MarginLayoutParams searchContainerLp =
|
||||
(MarginLayoutParams) mSearchContainer.getLayoutParams();
|
||||
|
||||
searchContainerLp.height = mLauncher.getDragLayer().getInsets().top
|
||||
+ mSearchContainerMinHeight;
|
||||
mSearchContainer.setLayoutParams(searchContainerLp);
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
return;
|
||||
}
|
||||
|
||||
// --- remove START when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
|
||||
|
||||
// Update the number of items in the grid before we measure the view
|
||||
grid.updateAppsViewNumCols();
|
||||
if (mNumAppsPerRow != grid.allAppsNumCols ||
|
||||
mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) {
|
||||
mNumAppsPerRow = grid.allAppsNumCols;
|
||||
|
@ -357,22 +287,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
// Determine if the key event was actual text, if so, focus the search bar and then dispatch
|
||||
// the key normally so that it can process this key event
|
||||
if (!mSearchBarController.isSearchFieldFocused() &&
|
||||
event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
final int unicodeChar = event.getUnicodeChar();
|
||||
final boolean isKeyNotWhitespace = unicodeChar > 0 &&
|
||||
!Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
|
||||
if (isKeyNotWhitespace) {
|
||||
boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
|
||||
event.getKeyCode(), event);
|
||||
if (gotKey && mSearchQueryBuilder.length() > 0) {
|
||||
mSearchBarController.focusSearchField();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSearchUiManager.preDispatchKeyEvent(event);
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
|
@ -439,43 +354,13 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
|
||||
if (apps != null) {
|
||||
mApps.setOrderedFilter(apps);
|
||||
mAppsRecyclerView.onSearchResultsChanged();
|
||||
mAdapter.setLastSearchQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppDiscoverySearchUpdate(@Nullable AppDiscoveryItem app,
|
||||
@NonNull AppDiscoveryUpdateState state) {
|
||||
if (!mLauncher.isDestroyed()) {
|
||||
mApps.onAppDiscoverySearchUpdate(app, state);
|
||||
mAppsRecyclerView.onSearchResultsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSearchResult() {
|
||||
if (mApps.setOrderedFilter(null)) {
|
||||
mAppsRecyclerView.onSearchResultsChanged();
|
||||
}
|
||||
|
||||
// Clear the search query
|
||||
mSearchQueryBuilder.clear();
|
||||
mSearchQueryBuilder.clearSpans();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
|
||||
targetParent.containerType = mAppsRecyclerView.getContainerType(v);
|
||||
}
|
||||
|
||||
public boolean shouldRestoreImeState() {
|
||||
return !TextUtils.isEmpty(mSearchInput.getText());
|
||||
return mSearchUiManager.shouldRestoreImeState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,6 +40,7 @@ import com.android.launcher3.R;
|
|||
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
|
||||
import com.android.launcher3.discovery.AppDiscoveryAppInfo;
|
||||
import com.android.launcher3.discovery.AppDiscoveryItemView;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -199,7 +200,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
|
|||
private int mAppsPerRow;
|
||||
|
||||
private BindViewCallback mBindViewCallback;
|
||||
private AllAppsSearchBarController mSearchController;
|
||||
private OnFocusChangeListener mIconFocusListener;
|
||||
|
||||
// The text to show when there are no search results and no market search handler.
|
||||
|
@ -241,10 +241,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
|
|||
mGridLayoutMgr.setSpanCount(appsPerRow);
|
||||
}
|
||||
|
||||
public void setSearchController(AllAppsSearchBarController searchController) {
|
||||
mSearchController = searchController;
|
||||
}
|
||||
|
||||
public void setIconFocusListener(OnFocusChangeListener focusListener) {
|
||||
mIconFocusListener = focusListener;
|
||||
}
|
||||
|
@ -256,7 +252,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
|
|||
public void setLastSearchQuery(String query) {
|
||||
Resources res = mLauncher.getResources();
|
||||
mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query);
|
||||
mMarketSearchIntent = mSearchController.createMarketSearchIntent(query);
|
||||
mMarketSearchIntent = PackageManagerHelper.getMarketSearchIntent(mLauncher, query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,8 +53,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
|
|||
private AllAppsBackgroundDrawable mEmptySearchBackground;
|
||||
private int mEmptySearchBackgroundTopOffset;
|
||||
|
||||
private HeaderElevationController mElevationController;
|
||||
|
||||
public AllAppsRecyclerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
@ -85,10 +83,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
|
|||
mFastScrollHelper = new AllAppsFastScrollHelper(this, apps);
|
||||
}
|
||||
|
||||
public void setElevationController(HeaderElevationController elevationController) {
|
||||
mElevationController = elevationController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of apps per row in this recycler view.
|
||||
*/
|
||||
|
@ -152,13 +146,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
|
|||
*/
|
||||
public void scrollToTop() {
|
||||
// Ensure we reattach the scrollbar if it was previously detached while fast-scrolling
|
||||
if (mScrollbar.isThumbDetached()) {
|
||||
mScrollbar.reattachThumbToScroll();
|
||||
}
|
||||
mScrollbar.reattachThumbToScroll();
|
||||
scrollToPosition(0);
|
||||
if (mElevationController != null) {
|
||||
mElevationController.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 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.allapps;
|
||||
|
||||
/**
|
||||
* The default search controller.
|
||||
*/
|
||||
public class DefaultAppSearchController extends AllAppsSearchBarController {
|
||||
|
||||
public DefaultAppSearchAlgorithm onInitializeSearch() {
|
||||
return new DefaultAppSearchAlgorithm(mApps.getApps());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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.allapps;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
|
||||
/**
|
||||
* Interface for controlling the Apps search UI.
|
||||
*/
|
||||
public interface SearchUiManager {
|
||||
|
||||
/**
|
||||
* Initializes the search manager.
|
||||
*/
|
||||
void initialize(AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView);
|
||||
|
||||
/**
|
||||
* Notifies the search manager that the apps-list has changed and the search UI should be
|
||||
* updated accordingly.
|
||||
*/
|
||||
void refreshSearchResult();
|
||||
|
||||
/**
|
||||
* Notifies the search manager to close any active search session.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Called before dispatching a key event, in case the search manager wants to initialize
|
||||
* some UI beforehand.
|
||||
*/
|
||||
void preDispatchKeyEvent(KeyEvent keyEvent);
|
||||
|
||||
/**
|
||||
* Returns true if the IME should be brought back.
|
||||
* TODO: Remove when removing support for opening all-apps in search mode.
|
||||
*/
|
||||
boolean shouldRestoreImeState();
|
||||
|
||||
/**
|
||||
* Starts the search UI
|
||||
* TODO: Remove when removing support for opening all-apps in search mode.
|
||||
*/
|
||||
void startAppsSearch();
|
||||
}
|
|
@ -13,12 +13,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
package com.android.launcher3.allapps.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Editable;
|
||||
|
@ -34,16 +31,18 @@ import android.widget.TextView.OnEditorActionListener;
|
|||
import com.android.launcher3.ExtendedEditText;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AlphabeticalAppsList;
|
||||
import com.android.launcher3.discovery.AppDiscoveryItem;
|
||||
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* An interface to a search box that AllApps can command.
|
||||
*/
|
||||
public abstract class AllAppsSearchBarController
|
||||
public class AllAppsSearchBarController
|
||||
implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener {
|
||||
|
||||
protected Launcher mLauncher;
|
||||
|
@ -88,9 +87,11 @@ public abstract class AllAppsSearchBarController
|
|||
}
|
||||
|
||||
/**
|
||||
* To be implemented by subclasses. This method will get called when the controller is set.
|
||||
* This method will get called when the controller is set.
|
||||
*/
|
||||
protected abstract DefaultAppSearchAlgorithm onInitializeSearch();
|
||||
public DefaultAppSearchAlgorithm onInitializeSearch() {
|
||||
return new DefaultAppSearchAlgorithm(mApps.getApps());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
@ -114,7 +115,7 @@ public abstract class AllAppsSearchBarController
|
|||
}
|
||||
}
|
||||
|
||||
protected void refreshSearchResult() {
|
||||
public void refreshSearchResult() {
|
||||
if (TextUtils.isEmpty(mQuery)) {
|
||||
return;
|
||||
}
|
||||
|
@ -135,7 +136,8 @@ public abstract class AllAppsSearchBarController
|
|||
if (query.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return mLauncher.startActivitySafely(v, createMarketSearchIntent(query), null);
|
||||
return mLauncher.startActivitySafely(v,
|
||||
PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,29 +187,11 @@ public abstract class AllAppsSearchBarController
|
|||
return mInput.isFocused();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new market search intent.
|
||||
*/
|
||||
public Intent createMarketSearchIntent(String query) {
|
||||
Uri marketSearchUri = Uri.parse("market://search")
|
||||
.buildUpon()
|
||||
.appendQueryParameter("c", "apps")
|
||||
.appendQueryParameter("q", query)
|
||||
.build();
|
||||
return new Intent(Intent.ACTION_VIEW).setData(marketSearchUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for getting search results.
|
||||
*/
|
||||
public interface Callbacks {
|
||||
|
||||
/**
|
||||
* Called when the bounds of the search bar has changed.
|
||||
*/
|
||||
@Deprecated
|
||||
void onBoundsChanged(Rect newBounds);
|
||||
|
||||
/**
|
||||
* Called when the search is complete.
|
||||
*
|
||||
|
@ -220,7 +204,6 @@ public abstract class AllAppsSearchBarController
|
|||
*/
|
||||
void clearSearchResult();
|
||||
|
||||
|
||||
/**
|
||||
* Called when the app discovery is providing an update of search, which can either be
|
||||
* START for starting a new discovery,
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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.allapps.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Selection;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.launcher3.ExtendedEditText;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter;
|
||||
import com.android.launcher3.allapps.AllAppsRecyclerView;
|
||||
import com.android.launcher3.allapps.AlphabeticalAppsList;
|
||||
import com.android.launcher3.allapps.SearchUiManager;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.discovery.AppDiscoveryItem;
|
||||
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
|
||||
import com.android.launcher3.graphics.TintedDrawableSpan;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Layout to contain the All-apps search UI.
|
||||
*/
|
||||
public class AppsSearchContainerLayout extends FrameLayout
|
||||
implements SearchUiManager, AllAppsSearchBarController.Callbacks {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final int mMinHeight;
|
||||
private final AllAppsSearchBarController mSearchBarController;
|
||||
private final SpannableStringBuilder mSearchQueryBuilder;
|
||||
private final HeaderElevationController mElevationController;
|
||||
|
||||
private ExtendedEditText mSearchInput;
|
||||
private AlphabeticalAppsList mApps;
|
||||
private AllAppsRecyclerView mAppsRecyclerView;
|
||||
private AllAppsGridAdapter mAdapter;
|
||||
|
||||
public AppsSearchContainerLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AppsSearchContainerLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AppsSearchContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
mMinHeight = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
|
||||
mSearchBarController = new AllAppsSearchBarController();
|
||||
mElevationController = new HeaderElevationController(this);
|
||||
|
||||
mSearchQueryBuilder = new SpannableStringBuilder();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mSearchInput = findViewById(R.id.search_box_input);
|
||||
|
||||
// Update the hint to contain the icon.
|
||||
// Prefix the original hint with two spaces. The first space gets replaced by the icon
|
||||
// using span. The second space is used for a singe space character between the hint
|
||||
// and the icon.
|
||||
SpannableString spanned = new SpannableString(" " + mSearchInput.getHint());
|
||||
spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
|
||||
0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
|
||||
mSearchInput.setHint(spanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
|
||||
!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
|
||||
getLayoutParams().height = mLauncher.getDragLayer().getInsets().top + mMinHeight;
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize(
|
||||
AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView) {
|
||||
mApps = appsList;
|
||||
mAppsRecyclerView = recyclerView;
|
||||
mAppsRecyclerView.addOnScrollListener(mElevationController);
|
||||
mAdapter = (AllAppsGridAdapter) mAppsRecyclerView.getAdapter();
|
||||
|
||||
mSearchBarController.initialize(appsList, mSearchInput, mLauncher, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshSearchResult() {
|
||||
mSearchBarController.refreshSearchResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
mElevationController.reset();
|
||||
mSearchBarController.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDispatchKeyEvent(KeyEvent event) {
|
||||
// Determine if the key event was actual text, if so, focus the search bar and then dispatch
|
||||
// the key normally so that it can process this key event
|
||||
if (!mSearchBarController.isSearchFieldFocused() &&
|
||||
event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
final int unicodeChar = event.getUnicodeChar();
|
||||
final boolean isKeyNotWhitespace = unicodeChar > 0 &&
|
||||
!Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
|
||||
if (isKeyNotWhitespace) {
|
||||
boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
|
||||
event.getKeyCode(), event);
|
||||
if (gotKey && mSearchQueryBuilder.length() > 0) {
|
||||
mSearchBarController.focusSearchField();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRestoreImeState() {
|
||||
return !TextUtils.isEmpty(mSearchInput.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAppsSearch() {
|
||||
if (mApps != null) {
|
||||
mSearchBarController.focusSearchField();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
|
||||
if (apps != null) {
|
||||
mApps.setOrderedFilter(apps);
|
||||
notifyResultChanged();
|
||||
mAdapter.setLastSearchQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSearchResult() {
|
||||
if (mApps.setOrderedFilter(null)) {
|
||||
notifyResultChanged();
|
||||
}
|
||||
|
||||
// Clear the search query
|
||||
mSearchQueryBuilder.clear();
|
||||
mSearchQueryBuilder.clearSpans();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppDiscoverySearchUpdate(
|
||||
@Nullable AppDiscoveryItem app, @NonNull AppDiscoveryUpdateState state) {
|
||||
if (!mLauncher.isDestroyed()) {
|
||||
mApps.onAppDiscoverySearchUpdate(app, state);
|
||||
notifyResultChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyResultChanged() {
|
||||
mElevationController.reset();
|
||||
mAppsRecyclerView.onSearchResultsChanged();
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
package com.android.launcher3.allapps.search;
|
||||
|
||||
import android.os.Handler;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.android.launcher3.allapps;
|
||||
package com.android.launcher3.allapps.search;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Outline;
|
|
@ -10,7 +10,6 @@ import android.widget.FrameLayout;
|
|||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherCallbacks;
|
||||
import com.android.launcher3.allapps.AllAppsSearchBarController;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
@ -197,11 +196,6 @@ public class LauncherExtension extends Launcher {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllAppsSearchBarController getAllAppsSearchBarController() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComponentKey> getPredictedApps() {
|
||||
// To debug app predictions, enable AlphabeticalAppsList#DEBUG_PREDICTIONS
|
||||
|
@ -213,11 +207,6 @@ public class LauncherExtension extends Launcher {
|
|||
return SEARCH_BAR_HEIGHT_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLauncherSearchCallback(Object callbacks) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
}
|
||||
|
|
|
@ -30,9 +30,11 @@ import android.os.UserHandle;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -149,4 +151,20 @@ public class PackageManagerHelper {
|
|||
.appendQueryParameter("id", packageName)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new market search intent.
|
||||
*/
|
||||
public static Intent getMarketSearchIntent(Context context, String query) {
|
||||
try {
|
||||
Intent intent = Intent.parseUri(context.getString(R.string.market_search_intent), 0);
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
intent.setData(
|
||||
intent.getData().buildUpon().appendQueryParameter("q", query).build());
|
||||
}
|
||||
return intent;
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
package com.android.launcher3.allapps.search;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.test.InstrumentationTestCase;
|
Loading…
Reference in New Issue