Merge "Show suggestion when user taps on folder's edit text" into ub-launcher3-master
This commit is contained in:
commit
bab1101b87
|
@ -44,7 +44,7 @@ public class ExtendedEditText extends EditText {
|
|||
* Implemented by listeners of the back key.
|
||||
*/
|
||||
public interface OnBackKeyListener {
|
||||
public boolean onBackKey();
|
||||
boolean onBackKey();
|
||||
}
|
||||
|
||||
private OnBackKeyListener mBackKeyListener;
|
||||
|
|
|
@ -297,16 +297,22 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
}
|
||||
|
||||
public void startEditingFolderName() {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mFolderName.setHint("");
|
||||
mIsEditingName = true;
|
||||
post(() -> {
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
if (TextUtils.isEmpty(mFolderName.getText())) {
|
||||
final String[] suggestedNames = new String[FolderNameProvider.SUGGEST_MAX];
|
||||
mLauncher.getFolderNameProvider().getSuggestedFolderName(getContext(),
|
||||
mInfo.contents, suggestedNames);
|
||||
mFolderName.setText(suggestedNames[0]);
|
||||
mFolderName.displayCompletions(Arrays.asList(suggestedNames).subList(1,
|
||||
suggestedNames.length));
|
||||
}
|
||||
}
|
||||
mFolderName.setHint("");
|
||||
mIsEditingName = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onBackKey() {
|
||||
// Convert to a string here to ensure that no other state associated with the text field
|
||||
|
@ -316,10 +322,18 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
mFolderIcon.onTitleChanged(newTitle);
|
||||
mLauncher.getModelWriter().updateItemInDatabase(mInfo);
|
||||
|
||||
if (TextUtils.isEmpty(mInfo.title)) {
|
||||
mFolderName.setHint(R.string.folder_hint_text);
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
mFolderName.setText(mInfo.title);
|
||||
// TODO: depending on whether the title was manually edited or automatically
|
||||
// suggested, apply different hint.
|
||||
mFolderName.setHint("");
|
||||
} else {
|
||||
mFolderName.setHint(null);
|
||||
if (TextUtils.isEmpty(mInfo.title)) {
|
||||
mFolderName.setHint(R.string.folder_hint_text);
|
||||
mFolderName.setText("");
|
||||
} else {
|
||||
mFolderName.setHint(null);
|
||||
}
|
||||
}
|
||||
|
||||
sendCustomAccessibilityEvent(
|
||||
|
@ -403,7 +417,11 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
mFolderName.setHint(null);
|
||||
} else {
|
||||
mFolderName.setText("");
|
||||
mFolderName.setHint(R.string.folder_hint_text);
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
mFolderName.setHint("");
|
||||
} else {
|
||||
mFolderName.setHint(R.string.folder_hint_text);
|
||||
}
|
||||
}
|
||||
// In case any children didn't come across during loading, clean up the folder accordingly
|
||||
mFolderIcon.post(() -> {
|
||||
|
@ -420,7 +438,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()
|
||||
&& TextUtils.isEmpty(mFolderName.getText().toString())) {
|
||||
if (suggestName.length > 0 && !TextUtils.isEmpty(suggestName[0])) {
|
||||
mFolderName.setHint(suggestName[0]);
|
||||
mFolderName.setHint("");
|
||||
mFolderName.setText(suggestName[0]);
|
||||
mInfo.title = suggestName[0];
|
||||
animateOpen(mInfo.contents, 0, true);
|
||||
|
@ -534,6 +552,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
openFolder.close(true);
|
||||
}
|
||||
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
mLauncher.getFolderNameProvider().load(getContext());
|
||||
}
|
||||
mContent.bindItems(items);
|
||||
centerAboutIcon();
|
||||
mItemsInvalidated = true;
|
||||
|
@ -1350,6 +1371,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||
return itemsOnCurrentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (v == mFolderName) {
|
||||
if (hasFocus) {
|
||||
|
|
|
@ -18,13 +18,16 @@ package com.android.launcher3.folder;
|
|||
import android.content.Context;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -38,16 +41,26 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
public class FolderNameProvider {
|
||||
|
||||
private static final String TAG = FeatureFlags.FOLDER_NAME_SUGGEST.getKey();
|
||||
private static final boolean DEBUG = FeatureFlags.FOLDER_NAME_SUGGEST.get();
|
||||
|
||||
/**
|
||||
* IME usually has up to 3 suggest slots. In total, there are 4 suggest slots as the folder
|
||||
* name edit box can also be used to provide suggestion.
|
||||
*/
|
||||
public static final int SUGGEST_MAX = 4;
|
||||
|
||||
/**
|
||||
* When inheriting class requires precaching, override this method.
|
||||
*/
|
||||
public void load(Context context) {}
|
||||
|
||||
public CharSequence getSuggestedFolderName(Context context,
|
||||
ArrayList<WorkspaceItemInfo> workspaceItemInfos, CharSequence[] candidates) {
|
||||
|
||||
CharSequence suggest;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(candidates));
|
||||
}
|
||||
// If all the icons are from work profile,
|
||||
// Then, suggest "Work" as the folder name
|
||||
List<WorkspaceItemInfo> distinctItemInfos = workspaceItemInfos.stream()
|
||||
|
@ -75,19 +88,28 @@ public class FolderNameProvider {
|
|||
// Place it as first viable suggestion and shift everything else
|
||||
info.ifPresent(i -> setAsFirstSuggestion(candidates, i.title.toString()));
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(candidates));
|
||||
}
|
||||
return candidates[0];
|
||||
}
|
||||
|
||||
private void setAsFirstSuggestion(CharSequence[] candidatesOut, CharSequence candidate) {
|
||||
for (int i = candidatesOut.length - 1; i > 0; i--) {
|
||||
if (TextUtils.isEmpty(candidatesOut[i])) {
|
||||
candidatesOut[i - 1] = candidatesOut[i];
|
||||
}
|
||||
candidatesOut[0] = candidate;
|
||||
if (contains(candidatesOut, candidate)) {
|
||||
return;
|
||||
}
|
||||
for (int i = candidatesOut.length - 1; i > 0; i--) {
|
||||
if (!TextUtils.isEmpty(candidatesOut[i - 1])) {
|
||||
candidatesOut[i] = candidatesOut[i - 1];
|
||||
}
|
||||
}
|
||||
candidatesOut[0] = candidate;
|
||||
}
|
||||
|
||||
private void setAsLastSuggestion(CharSequence[] candidatesOut, CharSequence candidate) {
|
||||
if (contains(candidatesOut, candidate)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < candidate.length(); i++) {
|
||||
if (TextUtils.isEmpty(candidatesOut[i])) {
|
||||
candidatesOut[i] = candidate;
|
||||
|
@ -95,6 +117,12 @@ public class FolderNameProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean contains(CharSequence[] list, CharSequence key) {
|
||||
return Arrays.asList(list).stream()
|
||||
.filter(s -> s != null)
|
||||
.anyMatch(s -> s.toString().equalsIgnoreCase(key.toString()));
|
||||
}
|
||||
|
||||
// This method can be moved to some Utility class location.
|
||||
private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
|
||||
Map<Object, Boolean> map = new ConcurrentHashMap<>();
|
||||
|
|
Loading…
Reference in New Issue