Add gallery suggestion to search bar
This commit is contained in:
1 parent
46bd8e4297
commit
934ec87390
8 files changed
+228
-15
No files matched your search
@@ -70,7 +70,9 @@ import com.hippo.ehviewer.client.EhUtils;
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.client.data.ListUrlBuilder;
|
||||
import com.hippo.ehviewer.client.exception.EhException;
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailUrlParser;
|
||||
import com.hippo.ehviewer.client.parser.GalleryListParser;
|
||||
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser;
|
||||
import com.hippo.ehviewer.dao.QuickSearch;
|
||||
import com.hippo.ehviewer.ui.CommonOperations;
|
||||
import com.hippo.ehviewer.ui.MainActivity;
|
||||
@@ -95,6 +97,7 @@ import com.hippo.yorozuya.ViewUtils;
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import junit.framework.Assert;
|
||||
|
||||
@@ -315,6 +318,92 @@ public final class GalleryListScene extends BaseScene
|
||||
searchBar.setEditTextHint(ssb);
|
||||
}
|
||||
|
||||
private void setSearchBarSuggestionProvider(SearchBar searchBar) {
|
||||
searchBar.setSuggestionProvider(text -> {
|
||||
GalleryDetailUrlParser.Result result1 = GalleryDetailUrlParser.parse(text, false);
|
||||
if (result1 != null) {
|
||||
return Collections.singletonList(new GalleryDetailUrlSuggestion(result1.gid, result1.token));
|
||||
}
|
||||
GalleryPageUrlParser.Result result2 = GalleryPageUrlParser.parse(text, false);
|
||||
if (result2 != null) {
|
||||
return Collections.singletonList(new GalleryPageUrlSuggestion(result2.gid, result2.pToken, result2.page));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private abstract class UrlSuggestion extends SearchBar.Suggestion {
|
||||
@Override
|
||||
public CharSequence getText(float textSize) {
|
||||
Drawable bookImage = DrawableManager.getDrawable(getContext2(), R.drawable.v_book_open_x24);
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(" ");
|
||||
ssb.append(getResources2().getString(R.string.gallery_list_search_bar_open_gallery));
|
||||
int imageSize = (int) (textSize * 1.25);
|
||||
if (bookImage != null) {
|
||||
bookImage.setBounds(0, 0, imageSize, imageSize);
|
||||
ssb.setSpan(new ImageSpan(bookImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return ssb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
startScene(createAnnouncer());
|
||||
|
||||
if (mState == STATE_SIMPLE_SEARCH) {
|
||||
setState(STATE_NORMAL);
|
||||
} else if (mState == STATE_SEARCH_SHOW_LIST) {
|
||||
setState(STATE_SEARCH);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Announcer createAnnouncer();
|
||||
|
||||
@Override
|
||||
public void onLongClick() { }
|
||||
}
|
||||
|
||||
private class GalleryDetailUrlSuggestion extends UrlSuggestion {
|
||||
private long mGid;
|
||||
private String mToken;
|
||||
|
||||
private GalleryDetailUrlSuggestion(long gid, String token) {
|
||||
mGid = gid;
|
||||
mToken = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Announcer createAnnouncer() {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GID_TOKEN);
|
||||
args.putLong(GalleryDetailScene.KEY_GID, mGid);
|
||||
args.putString(GalleryDetailScene.KEY_TOKEN, mToken);
|
||||
return new Announcer(GalleryDetailScene.class).setArgs(args);
|
||||
}
|
||||
}
|
||||
|
||||
private class GalleryPageUrlSuggestion extends UrlSuggestion {
|
||||
private long mGid;
|
||||
private String mPToken;
|
||||
private int mPage;
|
||||
|
||||
private GalleryPageUrlSuggestion(long gid, String pToken, int page) {
|
||||
mGid = gid;
|
||||
mPToken = pToken;
|
||||
mPage = page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Announcer createAnnouncer() {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ProgressScene.KEY_ACTION, ProgressScene.ACTION_GALLERY_TOKEN);
|
||||
args.putLong(ProgressScene.KEY_GID, mGid);
|
||||
args.putString(ProgressScene.KEY_PTOKEN, mPToken);
|
||||
args.putInt(ProgressScene.KEY_PAGE, mPage);
|
||||
return new Announcer(ProgressScene.class).setArgs(args);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getSuitableTitleForUrlBuilder(
|
||||
Resources resources, ListUrlBuilder urlBuilder, boolean appName) {
|
||||
@@ -432,6 +521,7 @@ public final class GalleryListScene extends BaseScene
|
||||
mSearchBar.setHelper(this);
|
||||
mSearchBar.setOnStateChangeListener(this);
|
||||
setSearchBarHint(context, mSearchBar);
|
||||
setSearchBarSuggestionProvider(mSearchBar);
|
||||
|
||||
mSearchLayout.setHelper(this);
|
||||
mSearchLayout.setPadding(mSearchLayout.getPaddingLeft(), mSearchLayout.getPaddingTop() + paddingTopSB,
|
||||
|
||||
@@ -38,7 +38,7 @@ import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
@@ -49,7 +49,6 @@ import com.hippo.yorozuya.MathUtils;
|
||||
import com.hippo.yorozuya.SimpleAnimatorListener;
|
||||
import com.hippo.yorozuya.ViewUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchBar extends CardView implements View.OnClickListener,
|
||||
@@ -84,11 +83,12 @@ public class SearchBar extends CardView implements View.OnClickListener,
|
||||
private ViewTransition mViewTransition;
|
||||
|
||||
private SearchDatabase mSearchDatabase;
|
||||
private List<String> mSuggestionList;
|
||||
private ArrayAdapter mSuggestionAdapter;
|
||||
private List<Suggestion> mSuggestionList;
|
||||
private SuggestionAdapter mSuggestionAdapter;
|
||||
|
||||
private Helper mHelper;
|
||||
private OnStateChangeListener mOnStateChangeListener;
|
||||
private SuggestionProvider mSuggestionProvider;
|
||||
|
||||
private boolean mAllowEmptySearch = true;
|
||||
|
||||
@@ -136,22 +136,18 @@ public class SearchBar extends CardView implements View.OnClickListener,
|
||||
mBaseHeight = getMeasuredHeight();
|
||||
|
||||
mSuggestionList = new ArrayList<>();
|
||||
mSuggestionAdapter = new ArrayAdapter<>(getContext(), R.layout.item_simple_list, mSuggestionList);
|
||||
mSuggestionAdapter = new SuggestionAdapter(LayoutInflater.from(getContext()));
|
||||
mListView.setAdapter(mSuggestionAdapter);
|
||||
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
String suggestion = mSuggestionList.get(MathUtils.clamp(position, 0, mSuggestionList.size() - 1));
|
||||
mEditText.setText(suggestion);
|
||||
mEditText.setSelection(mEditText.getText().length());
|
||||
mSuggestionList.get(position).onClick();
|
||||
}
|
||||
});
|
||||
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
String suggestion = mSuggestionList.get(MathUtils.clamp(position, 0, mSuggestionList.size() - 1));
|
||||
mSearchDatabase.deleteQuery(suggestion);
|
||||
updateSuggestions();
|
||||
mSuggestionList.get(position).onLongClick();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -166,10 +162,22 @@ public class SearchBar extends CardView implements View.OnClickListener,
|
||||
}
|
||||
|
||||
private void updateSuggestions() {
|
||||
String prefix = mEditText.getText().toString();
|
||||
String[] suggestions = mSearchDatabase.getSuggestions(prefix, 128);
|
||||
mSuggestionList.clear();
|
||||
Collections.addAll(mSuggestionList, suggestions);
|
||||
|
||||
String text = mEditText.getText().toString();
|
||||
|
||||
if (mSuggestionProvider != null) {
|
||||
List<Suggestion> suggestions = mSuggestionProvider.providerSuggestions(text);
|
||||
if (suggestions != null && !suggestions.isEmpty()) {
|
||||
mSuggestionList.addAll(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
String[] keywords = mSearchDatabase.getSuggestions(text, 128);
|
||||
for (String keyword : keywords) {
|
||||
mSuggestionList.add(new KeywordSuggestion(keyword));
|
||||
}
|
||||
|
||||
if (mSuggestionList.size() == 0) {
|
||||
removeListHeader();
|
||||
} else {
|
||||
@@ -199,6 +207,10 @@ public class SearchBar extends CardView implements View.OnClickListener,
|
||||
mOnStateChangeListener = listener;
|
||||
}
|
||||
|
||||
public void setSuggestionProvider(SuggestionProvider suggestionProvider) {
|
||||
mSuggestionProvider = suggestionProvider;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
mEditText.setText(text);
|
||||
}
|
||||
@@ -488,4 +500,82 @@ public class SearchBar extends CardView implements View.OnClickListener,
|
||||
|
||||
void onStateChange(SearchBar searchBar, int newState, int oldState, boolean animation);
|
||||
}
|
||||
|
||||
public interface SuggestionProvider {
|
||||
|
||||
List<Suggestion> providerSuggestions(String text);
|
||||
}
|
||||
|
||||
private class SuggestionAdapter extends BaseAdapter {
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
private SuggestionAdapter(LayoutInflater inflater) {
|
||||
mInflater = inflater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mSuggestionList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mSuggestionList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextView textView;
|
||||
if (convertView == null) {
|
||||
textView = (TextView) mInflater.inflate(R.layout.item_simple_list, parent, false);
|
||||
} else {
|
||||
textView = (TextView) convertView;
|
||||
}
|
||||
|
||||
textView.setText(mSuggestionList.get(position).getText(textView.getTextSize()));
|
||||
|
||||
return textView;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Suggestion {
|
||||
|
||||
public abstract CharSequence getText(float textSize);
|
||||
|
||||
public abstract void onClick();
|
||||
|
||||
public abstract void onLongClick();
|
||||
}
|
||||
|
||||
public class KeywordSuggestion extends Suggestion {
|
||||
|
||||
private String mKeyword;
|
||||
|
||||
private KeywordSuggestion(String keyword) {
|
||||
mKeyword = keyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getText(float textSize) {
|
||||
return mKeyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
mEditText.setText(mKeyword);
|
||||
mEditText.setSelection(mEditText.getText().length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick() {
|
||||
mSearchDatabase.deleteQuery(mKeyword);
|
||||
updateSuggestions();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user