Add search history

This commit is contained in:
seven332 committed 2015-04-22 12:52:06 +08:00
1 parent beec5d8776
commit be8ab2fcb2
5 files changed
+216 -43

No files matched your search

@@ -24,6 +24,7 @@ import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.ContentActivity;
import com.hippo.ehviewer.widget.ContentLayout;
import com.hippo.ehviewer.widget.SearchBar;
import com.hippo.ehviewer.widget.SearchDatabase;
import com.hippo.scene.Scene;
import com.hippo.scene.TransitionCurtain;
import com.hippo.util.Log;
@@ -37,6 +38,7 @@ class GalleryListScene extends Scene implements SearchBar.Helper{
private ContentActivity mActivity;
private Resources mResources;
private SearchDatabase mSearchDatabase;
private SearchBar mSearchBar;
private ContentLayout mContentLayout;
@@ -48,6 +50,7 @@ class GalleryListScene extends Scene implements SearchBar.Helper{
mActivity = (ContentActivity) getStageActivity();
mResources = mActivity.getResources();
mSearchDatabase = SearchDatabase.getInstance(getStageActivity());
mSearchBar = (SearchBar) findViewById(R.id.search_bar);
mContentLayout = (ContentLayout) findViewById(R.id.content_layout);
@@ -73,6 +76,7 @@ class GalleryListScene extends Scene implements SearchBar.Helper{
}, 1000);
}
@Override
protected void onGetFitPaddingBottom(int b) {
// TODO
}
@@ -90,5 +94,7 @@ class GalleryListScene extends Scene implements SearchBar.Helper{
@Override
public void onApplySearch(String query) {
Log.d("onApplySearch " + query);
mSearchDatabase.addQuery(query);
mSearchBar.setInNormalMode();
}
}
@@ -21,11 +21,12 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -49,7 +50,7 @@ import java.util.ArrayList;
import java.util.List;
public class SearchBar extends CardView implements View.OnClickListener,
TextView.OnEditorActionListener {
TextView.OnEditorActionListener, TextWatcher {
private static final long ANIMATION_TIME = 300;
@@ -60,7 +61,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
private float mProgress;
private SimpleImageView mMenuButton;
private TextView mLogoTextView;
private TextView mTitleTextView;
private SimpleImageView mActionButton;
private SearchEditText mEditText;
private ListView mList;
@@ -68,6 +69,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
private DrawerArrowDrawable mDrawerArrowDrawable;
private AddDeleteDrawable mAddDeleteDrawable;
private SearchDatabase mSearchDatabase;
private List<String> mSuggestionList;
private ArrayAdapter mSuggestionAdapter;
@@ -93,15 +95,17 @@ public class SearchBar extends CardView implements View.OnClickListener,
}
private void init(Context context) {
mSearchDatabase = SearchDatabase.getInstance(getContext());
setRadius(UiUtils.dp2pix(context, 2));
setCardElevation(UiUtils.dp2pix(context, 2));
setCardBackgroundColor(Color.WHITE);
setOnClickListener(this);
LayoutInflater.from(context).inflate(R.layout.widget_search_bar, this);
mMenuButton = (SimpleImageView) findViewById(R.id.menu);
mLogoTextView = (TextView) findViewById(R.id.logo);
mActionButton = (SimpleImageView) findViewById(R.id.action);
mMenuButton = (SimpleImageView) findViewById(R.id.search_menu);
mTitleTextView = (TextView) findViewById(R.id.search_title);
mActionButton = (SimpleImageView) findViewById(R.id.search_action);
mEditText = (SearchEditText) findViewById(R.id.search_edit_text);
mList = (ListView) findViewById(R.id.search_bar_list);
@@ -110,22 +114,28 @@ public class SearchBar extends CardView implements View.OnClickListener,
mMenuButton.setDrawable(mDrawerArrowDrawable);
mMenuButton.setOnClickListener(this);
mLogoTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Slabo.ttf"));
mActionButton.setDrawable(mAddDeleteDrawable);
mActionButton.setOnClickListener(this);
mEditText.setSearchBar(this);
mEditText.setOnEditorActionListener(this);
mEditText.addTextChangedListener(this);
mSuggestionList = new ArrayList<>();
mSuggestionList.add("aaaaaaaaaaaaaaaaaaaaa");
mSuggestionList.add("dfsgfewrewfes");
mSuggestionList.add("dehyklrthrhbdsrf");
mSuggestionList.add("粉色热污染份额为别人的");
mSuggestionAdapter = new ArrayAdapter<>(getContext(),
android.R.layout.simple_list_item_1, mSuggestionList);
mList.setAdapter(mSuggestionAdapter);
}
private void updateSuggestions() {
String prefix = mEditText.getText().toString();
String[] suggestions = mSearchDatabase.getSuggestions(prefix);
mSuggestionList.clear();
for (String suggestion : suggestions) {
mSuggestionList.add(suggestion);
}
mSuggestionAdapter.notifyDataSetChanged();
}
public void setHelper(Helper helper) {
mHelper = helper;
}
@@ -142,7 +152,6 @@ public class SearchBar extends CardView implements View.OnClickListener,
}
} else if (v == mActionButton) {
if (mInEditMode) {
// TODO when set prefix
mEditText.setText("");
} else {
mHelper.onClickAction();
@@ -168,12 +177,14 @@ public class SearchBar extends CardView implements View.OnClickListener,
if (!mInEditMode) {
mInEditMode = true;
setClickable(false);
ViewUtils.setVisibility(mLogoTextView, View.GONE);
ViewUtils.setVisibility(mTitleTextView, View.GONE);
ViewUtils.setVisibility(mEditText, View.VISIBLE);
mEditText.requestFocus();
// show ime
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
// update suggestion
updateSuggestions();
// start animator
ObjectAnimator oa1 = ObjectAnimator.ofFloat(mDrawerArrowDrawable, "progress", 0f, 1f);
oa1.setDuration(ANIMATION_TIME);
@@ -208,7 +219,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
if (mInEditMode) {
mInEditMode = false;
setOnClickListener(this);
ViewUtils.setVisibility(mLogoTextView, View.VISIBLE);
ViewUtils.setVisibility(mTitleTextView, View.VISIBLE);
ViewUtils.setVisibility(mEditText, View.GONE);
// hide ime
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -243,6 +254,10 @@ public class SearchBar extends CardView implements View.OnClickListener,
}
}
public void setTitle(String title) {
mTitleTextView.setText(title);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -282,6 +297,21 @@ public class SearchBar extends CardView implements View.OnClickListener,
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Empty
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Empty
}
@Override
public void afterTextChanged(Editable s) {
updateSuggestions();
}
public interface Helper {
void onClickMenu();
void onClickAction();
@@ -0,0 +1,159 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* 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
* 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.hippo.ehviewer.widget;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import com.hippo.util.Log;
import java.util.LinkedList;
import java.util.List;
public class SearchDatabase {
private static final String TAG = SearchDatabase.class.getSimpleName();
public static final String COLUMN_QUERY = "query";
public static final String COLUMN_DATE = "date";
private static final String DATABASE_NAME = "search_database.db";
private static final String TABLE_SUGGESTIONS = "suggestions";
private static final int MAX_HISTORY = 100;
private SQLiteDatabase mDatabase;
private static SearchDatabase sInstance;
public static SearchDatabase getInstance(Context context) {
if (sInstance == null) {
sInstance = new SearchDatabase(context.getApplicationContext());
}
return sInstance;
}
private SearchDatabase(Context context) {
DatabaseHelper databaseHelper = new DatabaseHelper(context);
mDatabase = databaseHelper.getWritableDatabase();
}
public String[] getSuggestions(String prefix) {
List<String> queryList = new LinkedList<>();
// TODO add limit
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM ").append(TABLE_SUGGESTIONS);
if (!TextUtils.isEmpty(prefix)) {
sb.append(" WHERE ").append(COLUMN_QUERY).append(" LIKE '")
.append(prefix).append("%'");
}
sb.append(" ORDER BY ").append(COLUMN_DATE).append(" DESC")
.append(" LIMIT 5");
Cursor cursor = mDatabase.rawQuery(sb.toString(), null);
int queryIndex = cursor.getColumnIndex(COLUMN_QUERY);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String suggestion = cursor.getString(queryIndex);
if (!prefix.equals(suggestion)) {
queryList.add(suggestion);
}
cursor.moveToNext();
}
}
cursor.close();
return queryList.toArray(new String[queryList.size()]);
}
public void addQuery(final String query) {
if (!TextUtils.isEmpty(query)) {
// Delete old first
deleteQuery(query);
// Add it to database
ContentValues values = new ContentValues();
values.put(COLUMN_QUERY, query);
values.put(COLUMN_DATE, System.currentTimeMillis());
mDatabase.insert(TABLE_SUGGESTIONS, null, values);
// Remove history if more than max
truncateHistory(MAX_HISTORY);
}
}
public void deleteQuery(final String query) {
mDatabase.delete(TABLE_SUGGESTIONS, COLUMN_DATE + "=?", new String[]{query});
}
public void clearQuery() {
truncateHistory(0);
}
/**
* Reduces the length of the history table, to prevent it from growing too large.
*
* @param maxEntries Max entries to leave in the table. 0 means remove all entries.
*/
protected void truncateHistory(int maxEntries) {
if (maxEntries < 0) {
throw new IllegalArgumentException();
}
try {
// null means "delete all". otherwise "delete but leave n newest"
String selection = null;
if (maxEntries > 0) {
selection = "_id IN " +
"(SELECT _id FROM " + TABLE_SUGGESTIONS +
" ORDER BY " + COLUMN_DATE + " DESC" +
" LIMIT -1 OFFSET " + String.valueOf(maxEntries) + ")";
}
mDatabase.delete(TABLE_SUGGESTIONS, selection, null);
} catch (RuntimeException e) {
Log.e(TAG, "truncateHistory", e);
}
}
/**
* Builds the database. This version has extra support for using the version field
* as a mode flags field, and configures the database columns depending on the mode bits
* (features) requested by the extending class.
*/
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_SUGGESTIONS + " (" +
"_id INTEGER PRIMARY KEY" +
"," + COLUMN_QUERY + " TEXT" +
"," + COLUMN_DATE + " LONG" +
");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SUGGESTIONS);
onCreate(db);
}
}
}
@@ -1,23 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* 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
* 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.hippo.util;
public class TextUtils {
public static final String STRING_EMPTY = "";
public static final String STRING_NULL = "null";
}