version:1.5
fix:迁移到奥乐云平台 add:
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.aoleyun.os.allapps.search;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import com.aoleyun.os.ExtendedEditText;
|
||||
import com.aoleyun.os.Launcher;
|
||||
import com.aoleyun.os.Utilities;
|
||||
import com.aoleyun.os.model.AppLaunchTracker;
|
||||
import com.aoleyun.os.util.ComponentKey;
|
||||
import com.aoleyun.os.util.PackageManagerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* An interface to a search box that AllApps can command.
|
||||
*/
|
||||
public class AllAppsSearchBarController
|
||||
implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener,
|
||||
OnFocusChangeListener {
|
||||
|
||||
protected Launcher mLauncher;
|
||||
protected Callbacks mCb;
|
||||
protected ExtendedEditText mInput;
|
||||
protected String mQuery;
|
||||
|
||||
protected SearchAlgorithm mSearchAlgorithm;
|
||||
|
||||
public void setVisibility(int visibility) {
|
||||
mInput.setVisibility(visibility);
|
||||
}
|
||||
/**
|
||||
* Sets the references to the apps model and the search result callback.
|
||||
*/
|
||||
public final void initialize(
|
||||
SearchAlgorithm searchAlgorithm, ExtendedEditText input,
|
||||
Launcher launcher, Callbacks cb) {
|
||||
mCb = cb;
|
||||
mLauncher = launcher;
|
||||
|
||||
mInput = input;
|
||||
mInput.addTextChangedListener(this);
|
||||
mInput.setOnEditorActionListener(this);
|
||||
mInput.setOnBackKeyListener(this);
|
||||
mInput.setOnFocusChangeListener(this);
|
||||
mSearchAlgorithm = searchAlgorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
mQuery = s.toString();
|
||||
if (mQuery.isEmpty()) {
|
||||
mSearchAlgorithm.cancel(true);
|
||||
mCb.clearSearchResult();
|
||||
} else {
|
||||
mSearchAlgorithm.cancel(false);
|
||||
mSearchAlgorithm.doSearch(mQuery, mCb);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshSearchResult() {
|
||||
if (TextUtils.isEmpty(mQuery)) {
|
||||
return;
|
||||
}
|
||||
// If play store continues auto updating an app, we want to show partial result.
|
||||
mSearchAlgorithm.cancel(false);
|
||||
mSearchAlgorithm.doSearch(mQuery, mCb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
// Skip if it's not the right action
|
||||
if (actionId != EditorInfo.IME_ACTION_SEARCH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip if the query is empty
|
||||
String query = v.getText().toString();
|
||||
if (query.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return mLauncher.startActivitySafely(v,
|
||||
PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null,
|
||||
AppLaunchTracker.CONTAINER_SEARCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackKey() {
|
||||
// Only hide the search field if there is no query
|
||||
String query = Utilities.trim(mInput.getEditableText().toString());
|
||||
if (query.isEmpty()) {
|
||||
reset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
mInput.hideKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the search bar state.
|
||||
*/
|
||||
public void reset() {
|
||||
mCb.clearSearchResult();
|
||||
mInput.reset();
|
||||
mQuery = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the search field to handle key events.
|
||||
*/
|
||||
public void focusSearchField() {
|
||||
mInput.showKeyboard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the search field is focused.
|
||||
*/
|
||||
public boolean isSearchFieldFocused() {
|
||||
return mInput.isFocused();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for getting search results.
|
||||
*/
|
||||
public interface Callbacks {
|
||||
|
||||
/**
|
||||
* Called when the search is complete.
|
||||
*
|
||||
* @param apps sorted list of matching components or null if in case of failure.
|
||||
*/
|
||||
void onSearchResult(String query, ArrayList<ComponentKey> apps);
|
||||
|
||||
/**
|
||||
* Called when the search results should be cleared.
|
||||
*/
|
||||
void clearSearchResult();
|
||||
}
|
||||
|
||||
}
|
||||
220
src/com/aoleyun/os/allapps/search/AppsSearchContainerLayout.java
Normal file
220
src/com/aoleyun/os/allapps/search/AppsSearchContainerLayout.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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.aoleyun.os.allapps.search;
|
||||
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.getSize;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
|
||||
import static com.aoleyun.os.LauncherState.ALL_APPS_HEADER;
|
||||
import static com.aoleyun.os.Utilities.prefixTextWithIcon;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.text.Selection;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.aoleyun.os.DeviceProfile;
|
||||
import com.aoleyun.os.ExtendedEditText;
|
||||
import com.aoleyun.os.Insettable;
|
||||
import com.aoleyun.os.Launcher;
|
||||
import com.aoleyun.os.R;
|
||||
import com.aoleyun.os.allapps.AllAppsContainerView;
|
||||
import com.aoleyun.os.allapps.AllAppsStore;
|
||||
import com.aoleyun.os.allapps.AlphabeticalAppsList;
|
||||
import com.aoleyun.os.allapps.SearchUiManager;
|
||||
import com.aoleyun.os.anim.PropertySetter;
|
||||
import com.aoleyun.os.util.ComponentKey;
|
||||
import com.aoleyun.os.icons.IconNormalizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Layout to contain the All-apps search UI.
|
||||
*/
|
||||
public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
implements SearchUiManager, AllAppsSearchBarController.Callbacks,
|
||||
AllAppsStore.OnUpdateListener, Insettable {
|
||||
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final AllAppsSearchBarController mSearchBarController;
|
||||
private final SpannableStringBuilder mSearchQueryBuilder;
|
||||
|
||||
private AlphabeticalAppsList mApps;
|
||||
private AllAppsContainerView mAppsView;
|
||||
|
||||
// This value was used to position the QSB. We store it here for translationY animations.
|
||||
private final float mFixedTranslationY;
|
||||
private final float mMarginTopAdjusting;
|
||||
|
||||
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);
|
||||
mSearchBarController = new AllAppsSearchBarController();
|
||||
|
||||
mSearchQueryBuilder = new SpannableStringBuilder();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
|
||||
mFixedTranslationY = getTranslationY();
|
||||
mMarginTopAdjusting = mFixedTranslationY - getPaddingTop();
|
||||
|
||||
setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mLauncher.getAppsView().getAppsStore().addUpdateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mLauncher.getAppsView().getAppsStore().removeUpdateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// Update the width to match the grid padding
|
||||
DeviceProfile dp = mLauncher.getDeviceProfile();
|
||||
int myRequestedWidth = getSize(widthMeasureSpec);
|
||||
int rowWidth = myRequestedWidth - mAppsView.getActiveRecyclerView().getPaddingLeft()
|
||||
- mAppsView.getActiveRecyclerView().getPaddingRight();
|
||||
|
||||
int cellWidth = DeviceProfile.calculateCellWidth(rowWidth, dp.inv.numHotseatIcons);
|
||||
int iconVisibleSize = Math.round(IconNormalizer.ICON_VISIBLE_AREA_FACTOR * dp.iconSizePx);
|
||||
int iconPadding = cellWidth - iconVisibleSize;
|
||||
|
||||
int myWidth = rowWidth - iconPadding + getPaddingLeft() + getPaddingRight();
|
||||
super.onMeasure(makeMeasureSpec(myWidth, EXACTLY), heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
// Shift the widget horizontally so that its centered in the parent (b/63428078)
|
||||
View parent = (View) getParent();
|
||||
int availableWidth = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight();
|
||||
int myWidth = right - left;
|
||||
int expectedLeft = parent.getPaddingLeft() + (availableWidth - myWidth) / 2;
|
||||
int shift = expectedLeft - left;
|
||||
setTranslationX(shift);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AllAppsContainerView appsView) {
|
||||
mApps = appsView.getApps();
|
||||
mAppsView = appsView;
|
||||
mSearchBarController.initialize(
|
||||
new DefaultAppSearchAlgorithm(mApps.getApps()), this, mLauncher, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppsUpdated() {
|
||||
mSearchBarController.refreshSearchResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetSearch() {
|
||||
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 void onSearchResult(String query, ArrayList<ComponentKey> apps) {
|
||||
if (apps != null) {
|
||||
mApps.setOrderedFilter(apps);
|
||||
notifyResultChanged();
|
||||
mAppsView.setLastSearchQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSearchResult() {
|
||||
if (mApps.setOrderedFilter(null)) {
|
||||
notifyResultChanged();
|
||||
}
|
||||
|
||||
// Clear the search query
|
||||
mSearchQueryBuilder.clear();
|
||||
mSearchQueryBuilder.clearSpans();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
mAppsView.onClearSearchResult();
|
||||
}
|
||||
|
||||
private void notifyResultChanged() {
|
||||
mAppsView.onSearchResultsChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsets(Rect insets) {
|
||||
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
|
||||
mlp.topMargin = Math.round(Math.max(-mFixedTranslationY, insets.top - mMarginTopAdjusting));
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getScrollRangeDelta(Rect insets) {
|
||||
if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
|
||||
return 0;
|
||||
} else {
|
||||
int topMargin = Math.round(Math.max(
|
||||
-mFixedTranslationY, insets.top - mMarginTopAdjusting));
|
||||
return insets.bottom + topMargin + mFixedTranslationY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentVisibility(int visibleElements, PropertySetter setter,
|
||||
Interpolator interpolator) {
|
||||
setter.setViewAlpha(this, (visibleElements & ALL_APPS_HEADER) != 0 ? 1 : 0, interpolator);
|
||||
}
|
||||
}
|
||||
184
src/com/aoleyun/os/allapps/search/DefaultAppSearchAlgorithm.java
Normal file
184
src/com/aoleyun/os/allapps/search/DefaultAppSearchAlgorithm.java
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.aoleyun.os.allapps.search;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import com.aoleyun.os.AppInfo;
|
||||
import com.aoleyun.os.util.ComponentKey;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The default search implementation.
|
||||
*/
|
||||
public class DefaultAppSearchAlgorithm implements SearchAlgorithm {
|
||||
|
||||
private final List<AppInfo> mApps;
|
||||
protected final Handler mResultHandler;
|
||||
|
||||
public DefaultAppSearchAlgorithm(List<AppInfo> apps) {
|
||||
mApps = apps;
|
||||
mResultHandler = new Handler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(boolean interruptActiveRequests) {
|
||||
if (interruptActiveRequests) {
|
||||
mResultHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSearch(final String query,
|
||||
final AllAppsSearchBarController.Callbacks callback) {
|
||||
final ArrayList<ComponentKey> result = getTitleMatchResult(query);
|
||||
mResultHandler.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onSearchResult(query, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ArrayList<ComponentKey> getTitleMatchResult(String query) {
|
||||
// Do an intersection of the words in the query and each title, and filter out all the
|
||||
// apps that don't match all of the words in the query.
|
||||
final String queryTextLower = query.toLowerCase();
|
||||
final ArrayList<ComponentKey> result = new ArrayList<>();
|
||||
StringMatcher matcher = StringMatcher.getInstance();
|
||||
for (AppInfo info : mApps) {
|
||||
if (matches(info, queryTextLower, matcher)) {
|
||||
result.add(info.toComponentKey());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean matches(AppInfo info, String query, StringMatcher matcher) {
|
||||
int queryLength = query.length();
|
||||
|
||||
String title = info.title.toString();
|
||||
int titleLength = title.length();
|
||||
|
||||
if (titleLength < queryLength || queryLength <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int lastType;
|
||||
int thisType = Character.UNASSIGNED;
|
||||
int nextType = Character.getType(title.codePointAt(0));
|
||||
|
||||
int end = titleLength - queryLength;
|
||||
for (int i = 0; i <= end; i++) {
|
||||
lastType = thisType;
|
||||
thisType = nextType;
|
||||
nextType = i < (titleLength - 1) ?
|
||||
Character.getType(title.codePointAt(i + 1)) : Character.UNASSIGNED;
|
||||
if (isBreak(thisType, lastType, nextType) &&
|
||||
matcher.matches(query, title.substring(i, i + queryLength))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current point should be a break point. Following cases
|
||||
* are considered as break points:
|
||||
* 1) Any non space character after a space character
|
||||
* 2) Any digit after a non-digit character
|
||||
* 3) Any capital character after a digit or small character
|
||||
* 4) Any capital character before a small character
|
||||
*/
|
||||
private static boolean isBreak(int thisType, int prevType, int nextType) {
|
||||
switch (prevType) {
|
||||
case Character.UNASSIGNED:
|
||||
case Character.SPACE_SEPARATOR:
|
||||
case Character.LINE_SEPARATOR:
|
||||
case Character.PARAGRAPH_SEPARATOR:
|
||||
return true;
|
||||
}
|
||||
switch (thisType) {
|
||||
case Character.UPPERCASE_LETTER:
|
||||
if (nextType == Character.UPPERCASE_LETTER) {
|
||||
return true;
|
||||
}
|
||||
// Follow through
|
||||
case Character.TITLECASE_LETTER:
|
||||
// Break point if previous was not a upper case
|
||||
return prevType != Character.UPPERCASE_LETTER;
|
||||
case Character.LOWERCASE_LETTER:
|
||||
// Break point if previous was not a letter.
|
||||
return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED;
|
||||
case Character.DECIMAL_DIGIT_NUMBER:
|
||||
case Character.LETTER_NUMBER:
|
||||
case Character.OTHER_NUMBER:
|
||||
// Break point if previous was not a number
|
||||
return !(prevType == Character.DECIMAL_DIGIT_NUMBER
|
||||
|| prevType == Character.LETTER_NUMBER
|
||||
|| prevType == Character.OTHER_NUMBER);
|
||||
case Character.MATH_SYMBOL:
|
||||
case Character.CURRENCY_SYMBOL:
|
||||
case Character.OTHER_PUNCTUATION:
|
||||
case Character.DASH_PUNCTUATION:
|
||||
// Always a break point for a symbol
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringMatcher {
|
||||
|
||||
private static final char MAX_UNICODE = '\uFFFF';
|
||||
|
||||
private final Collator mCollator;
|
||||
|
||||
StringMatcher() {
|
||||
// On android N and above, Collator uses ICU implementation which has a much better
|
||||
// support for non-latin locales.
|
||||
mCollator = Collator.getInstance();
|
||||
mCollator.setStrength(Collator.PRIMARY);
|
||||
mCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if {@param query} is a prefix of {@param target}
|
||||
*/
|
||||
public boolean matches(String query, String target) {
|
||||
switch (mCollator.compare(query, target)) {
|
||||
case 0:
|
||||
return true;
|
||||
case -1:
|
||||
// The target string can contain a modifier which would make it larger than
|
||||
// the query string (even though the length is same). If the query becomes
|
||||
// larger after appending a unicode character, it was originally a prefix of
|
||||
// the target string and hence should match.
|
||||
return mCollator.compare(query + MAX_UNICODE, target) > -1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static StringMatcher getInstance() {
|
||||
return new StringMatcher();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/com/aoleyun/os/allapps/search/SearchAlgorithm.java
Normal file
32
src/com/aoleyun/os/allapps/search/SearchAlgorithm.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.aoleyun.os.allapps.search;
|
||||
|
||||
/**
|
||||
* An interface for handling search.
|
||||
*/
|
||||
public interface SearchAlgorithm {
|
||||
|
||||
/**
|
||||
* Performs search and sends the result to the callback.
|
||||
*/
|
||||
void doSearch(String query, AllAppsSearchBarController.Callbacks callback);
|
||||
|
||||
/**
|
||||
* Cancels any active request.
|
||||
*/
|
||||
void cancel(boolean interruptActiveRequests);
|
||||
}
|
||||
Reference in New Issue
Block a user