From cde8aa7f62b2c3d05016469bdd19191da5f01240 Mon Sep 17 00:00:00 2001 From: seven332 Date: Sun, 8 Feb 2015 14:06:30 +0800 Subject: [PATCH] Improve search --- app/src/main/AndroidManifest.xml | 2 +- .../hippo/ehviewer/ui/ContentActivity.java | 17 ++ .../ehviewer/ui/fragment/SearchFragment.java | 178 +++++++++++++++++- .../com/hippo/widget/DrawerFrameLayout.java | 65 +++++++ .../java/com/hippo/widget/PrefixEditText.java | 98 ++++++++++ .../main/res/layout-land/activity_start.xml | 3 +- app/src/main/res/layout/activity_content.xml | 42 ++++- app/src/main/res/layout/activity_start.xml | 3 +- app/src/main/res/layout/draw_left.xml | 9 +- app/src/main/res/layout/fragment_search.xml | 32 ++-- .../main/res/layout/scene_gallery_detail.xml | 3 +- .../main/res/layout/scene_gallery_list.xml | 3 +- app/src/main/res/layout/search_category.xml | 42 +++++ app/src/main/res/layout/search_normal.xml | 52 +++++ .../main/res/layout/widget_category_table.xml | 3 +- .../layout/widget_float_label_edit_text.xml | 3 +- app/src/main/res/values-land/dimens.xml | 22 +++ app/src/main/res/values-sw600dp/dimens.xml | 23 +++ app/src/main/res/values-sw720dp/dimens.xml | 4 + app/src/main/res/values-v19/themes.xml | 5 + app/src/main/res/values-v21/themes.xml | 27 +++ app/src/main/res/values-zh-rCN/strings.xml | 28 +++ app/src/main/res/values/colors.xml | 8 +- app/src/main/res/values/dimens.xml | 14 ++ app/src/main/res/values/strings.xml | 9 + app/src/main/res/values/styles.xml | 8 + app/src/main/res/values/themes.xml | 9 +- 27 files changed, 665 insertions(+), 47 deletions(-) create mode 100644 app/src/main/java/com/hippo/widget/DrawerFrameLayout.java create mode 100644 app/src/main/java/com/hippo/widget/PrefixEditText.java create mode 100644 app/src/main/res/layout/search_category.xml create mode 100644 app/src/main/res/layout/search_normal.xml create mode 100644 app/src/main/res/values-land/dimens.xml create mode 100644 app/src/main/res/values-sw600dp/dimens.xml create mode 100644 app/src/main/res/values-v21/themes.xml create mode 100644 app/src/main/res/values-zh-rCN/strings.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bb8dfd1e3..63061bd85 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,7 +41,7 @@ android:name="com.hippo.ehviewer.ui.ContentActivity" android:configChanges="screenSize|uiMode" android:label="@string/app_name" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme.Content"> diff --git a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java index 77b1b2302..04e187917 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java @@ -15,17 +15,25 @@ package com.hippo.ehviewer.ui; +import android.content.res.Resources; +import android.graphics.Color; import android.os.Bundle; +import android.support.v4.view.ViewCompat; import android.support.v4.widget.DrawerLayout; +import android.support.v7.widget.Toolbar; import android.widget.FrameLayout; import com.hippo.ehviewer.R; import com.hippo.ehviewer.ui.scene.GalleryListScene; import com.hippo.scene.StageActivity; +import com.hippo.util.UiUtils; public class ContentActivity extends StageActivity { + private Resources mResources; + private DrawerLayout mDrawerLayout; + private Toolbar mToolbar; private FrameLayout mStage; @Override @@ -33,9 +41,18 @@ public class ContentActivity extends StageActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_content); + mResources = getResources(); + mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); + mToolbar = (Toolbar) mDrawerLayout.findViewById(R.id.toolbar); mStage = (FrameLayout) mDrawerLayout.findViewById(R.id.stage); + setSupportActionBar(mToolbar); + + mToolbar.setTitleTextColor(Color.WHITE); + ViewCompat.setElevation(mToolbar, UiUtils.dp2pix(4)); // TODO + + mDrawerLayout.setStatusBarBackground(R.color.theme_primary_dark); startFirstScene(GalleryListScene.class); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/SearchFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/SearchFragment.java index a137dab9e..6e8d90258 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/SearchFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/SearchFragment.java @@ -15,30 +15,206 @@ package com.hippo.ehviewer.ui.fragment; +import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v4.view.ViewCompat; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.FrameLayout; +import android.widget.TextView; import com.hippo.ehviewer.R; import com.hippo.ehviewer.data.GalleryListUrlBuilder; +import com.hippo.ehviewer.widget.CategoryTable; +import com.hippo.util.UiUtils; +import com.hippo.util.ViewUtils; +import com.hippo.widget.PrefixEditText; -public class SearchFragment extends Fragment { +public class SearchFragment extends Fragment implements CompoundButton.OnCheckedChangeListener { + + private static final int SEARCH_TYPE_NORMAL = 0; + private static final int SEARCH_TYPE_TAG = 1; + private static final int SEARCH_TYPE_IMAGE = 2; + + private static final int TYPE_NORMAL = 0; + private static final int TYPE_NORMAL_ADVANCE = 1; + private static final int TYPE_TAG = 2; + private static final int TYPE_IMAGE = 3; + + private static final int[] SEARCH_ITEM_COUNT_ARRAY = { + 2, 1, 1 + }; + + private Activity mActivity; + + private int mSearchType = SEARCH_TYPE_NORMAL; + private boolean mEnableAdvance; private OnSearchListener mOnSearchListener; + private RecyclerView mContainer; + private View mNormalView; + private CategoryTable mTableCategory; + private CheckBox mCheckSpecifyAuthor; + private PrefixEditText mTextSearch; + private CheckBox mCheckEnableAdvance; + + private LinearLayoutManager mLayoutManager; + private SearchAdapter mAdapter; + public void setOnSearchListener(OnSearchListener listener) { mOnSearchListener = listener; } public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) { + mActivity = getActivity(); View mRootView = inflater.inflate(R.layout.fragment_search, container, false); + + mContainer = (RecyclerView) mRootView.findViewById(R.id.search_container); + + mLayoutManager = new LinearLayoutManager(mActivity); + mAdapter = new SearchAdapter(); + mContainer.setLayoutManager(mLayoutManager); + mContainer.setAdapter(mAdapter); + mContainer.setHasFixedSize(true); + return mRootView; } + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView == mCheckSpecifyAuthor) { + mTextSearch.setPrefix(isChecked ? "uploader:" : null); + } else if (buttonView == mCheckEnableAdvance) { + mEnableAdvance = isChecked; + if (mSearchType == SEARCH_TYPE_NORMAL) { + if (isChecked) { + mAdapter.notifyItemInserted(1); + } else { + mAdapter.notifyItemRemoved(1); + } + } + } + } + + private class SearchHolder extends RecyclerView.ViewHolder { + + public TextView title; + public FrameLayout content; + + public SearchHolder(View itemView) { + super(itemView); + + title = (TextView) itemView.findViewById(R.id.category_title); + content = (FrameLayout) itemView.findViewById(R.id.category_content); + } + } + + private class SearchAdapter extends RecyclerView.Adapter { + + LayoutInflater mInflater; + + public SearchAdapter() { + mInflater = mActivity.getLayoutInflater(); + } + + @Override + public int getItemCount() { + int count = SEARCH_ITEM_COUNT_ARRAY[mSearchType]; + if (mSearchType == SEARCH_TYPE_NORMAL && !mEnableAdvance) { + count--; + } + return count; + } + + @Override + public int getItemViewType(int position) { + // Each item is different + int type = 0; + for (int i = 0; i < mSearchType; i++) { + type += SEARCH_ITEM_COUNT_ARRAY[i]; + } + type += position; + + return type; + } + + @Override + public SearchHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = mInflater.inflate(R.layout.search_category, parent, false); + + ViewCompat.setElevation(view, UiUtils.dp2pix(4)); // TODO + + SearchHolder holder = new SearchHolder(view); + + switch (viewType) { + case TYPE_NORMAL:{ + bindNormalView(holder); + break; + } + case TYPE_NORMAL_ADVANCE: { + bindAdvanceView(holder); + break; + } + case TYPE_TAG: { + bindTagView(holder); + break; + } + case TYPE_IMAGE: { + bindImageView(holder); + break; + } + } + + return holder; + } + + @Override + public void onBindViewHolder(SearchHolder holder, int position) { + // Empty, bind view in create view + } + + private void bindNormalView(SearchHolder holder) { + holder.title.setText(R.string.search_normal); + + if (mNormalView == null) { + mInflater.inflate(R.layout.search_normal, holder.content); + mNormalView = holder.content.getChildAt(0); + mTableCategory = (CategoryTable) mNormalView.findViewById(R.id.search_category_table); + mCheckSpecifyAuthor = (CheckBox) mNormalView.findViewById(R.id.search_specify_author); + mTextSearch = (PrefixEditText) mNormalView.findViewById(R.id.search_text); + mCheckEnableAdvance = (CheckBox) mNormalView.findViewById(R.id.search_enable_advance); + + mCheckSpecifyAuthor.setOnCheckedChangeListener(SearchFragment.this); + mCheckEnableAdvance.setOnCheckedChangeListener(SearchFragment.this); + } else { + ViewUtils.removeFromParent(mNormalView); + holder.content.addView(mNormalView); + } + + } + + private void bindAdvanceView(SearchHolder holder) { + holder.title.setText(R.string.search_advance); + } + + private void bindTagView(SearchHolder holder) { + holder.title.setText(R.string.search_tag); + } + + private void bindImageView(SearchHolder holder) { + holder.title.setText(R.string.search_image); + } + } + public interface OnSearchListener { public void onSearch(GalleryListUrlBuilder glub); } diff --git a/app/src/main/java/com/hippo/widget/DrawerFrameLayout.java b/app/src/main/java/com/hippo/widget/DrawerFrameLayout.java new file mode 100644 index 000000000..25a004a7a --- /dev/null +++ b/app/src/main/java/com/hippo/widget/DrawerFrameLayout.java @@ -0,0 +1,65 @@ +/* + * 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.widget; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +public class DrawerFrameLayout extends FrameLayout { + + private static final int[] MAX_ATTRS = {android.R.attr.maxWidth}; + + private int mMaxWidth = -1; + + public DrawerFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs, 0, 0); + } + + public DrawerFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs, defStyleAttr, 0); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public DrawerFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs, defStyleAttr, defStyleRes); + } + + private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + final TypedArray a = context.obtainStyledAttributes(attrs, MAX_ATTRS, defStyleAttr, defStyleRes); + mMaxWidth = a.getDimensionPixelSize(0, -1); + a.recycle(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); + + if (mMaxWidth > 0) { + widthSpecSize = Math.min(mMaxWidth, widthSpecSize); + widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSpecSize, + MeasureSpec.EXACTLY); + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } +} diff --git a/app/src/main/java/com/hippo/widget/PrefixEditText.java b/app/src/main/java/com/hippo/widget/PrefixEditText.java new file mode 100644 index 000000000..470bdd6bb --- /dev/null +++ b/app/src/main/java/com/hippo/widget/PrefixEditText.java @@ -0,0 +1,98 @@ +/* + * 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.widget; + +import android.content.Context; +import android.text.Editable; +import android.text.Selection; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.widget.AutoCompleteTextView; + +public class PrefixEditText extends AutoCompleteTextView + implements TextWatcher { + + private Context mContext; + private String mPrefix; + + public PrefixEditText(Context context) { + super(context); + init(context); + } + + public PrefixEditText(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public PrefixEditText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + private void init(Context context) { + mContext = context; + addTextChangedListener(this); + } + + public void setPrefix(int resId) { + setPrefix(mContext.getString(resId)); + } + + public void setPrefix(String prefix) { + mPrefix = prefix; + setText(mPrefix); + if (mPrefix != null) { + Selection.setSelection(getText(), mPrefix.length()); + } + } + + @Override + protected void onSelectionChanged(int selStart, int selEnd) { + super.onSelectionChanged(selStart, selEnd); + if (mPrefix != null) { + int newSelStart = selStart; + int newSelEnd = selEnd; + int prefixLength = mPrefix.length(); + if (newSelStart < prefixLength) { + newSelStart = prefixLength; + } + if (newSelEnd < prefixLength) { + newSelEnd = prefixLength; + } + setSelection(newSelStart, newSelEnd); + } + } + + @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) { + if(mPrefix != null && !s.toString().startsWith(mPrefix)){ + setText(mPrefix); + setSelection(mPrefix.length()); + } + } + +} diff --git a/app/src/main/res/layout-land/activity_start.xml b/app/src/main/res/layout-land/activity_start.xml index 6330ac44b..8ef73c7ea 100644 --- a/app/src/main/res/layout-land/activity_start.xml +++ b/app/src/main/res/layout-land/activity_start.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - - + android:layout_height="match_parent" + android:fitsSystemWindows="true"> - + android:layout_height="match_parent" + android:orientation="vertical"> - + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_start.xml b/app/src/main/res/layout/activity_start.xml index 608894ee3..c592eec75 100644 --- a/app/src/main/res/layout/activity_start.xml +++ b/app/src/main/res/layout/activity_start.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - - + android:orientation="vertical"> diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index fda2f620b..b48663fb3 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -13,26 +13,16 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + android:layout_height="match_parent" + android:paddingLeft="@dimen/search_padding_start" + android:paddingRight="@dimen/search_padding_end" + android:paddingTop="@dimen/search_padding_top" + android:paddingBottom="@dimen/search_padding_bottom" + android:fitsSystemWindows="true" + android:clipToPadding="false"> - - - - - - - + diff --git a/app/src/main/res/layout/scene_gallery_detail.xml b/app/src/main/res/layout/scene_gallery_detail.xml index f67f21ba3..42797ff94 100644 --- a/app/src/main/res/layout/scene_gallery_detail.xml +++ b/app/src/main/res/layout/scene_gallery_detail.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - diff --git a/app/src/main/res/layout/scene_gallery_list.xml b/app/src/main/res/layout/scene_gallery_list.xml index fe8769ca2..5c2053f44 100644 --- a/app/src/main/res/layout/scene_gallery_list.xml +++ b/app/src/main/res/layout/scene_gallery_list.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - diff --git a/app/src/main/res/layout/search_category.xml b/app/src/main/res/layout/search_category.xml new file mode 100644 index 000000000..15ba138bb --- /dev/null +++ b/app/src/main/res/layout/search_category.xml @@ -0,0 +1,42 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/search_normal.xml b/app/src/main/res/layout/search_normal.xml new file mode 100644 index 000000000..91ab03e4f --- /dev/null +++ b/app/src/main/res/layout/search_normal.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_category_table.xml b/app/src/main/res/layout/widget_category_table.xml index 7861b86b1..23dba62f2 100644 --- a/app/src/main/res/layout/widget_category_table.xml +++ b/app/src/main/res/layout/widget_category_table.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + diff --git a/app/src/main/res/layout/widget_float_label_edit_text.xml b/app/src/main/res/layout/widget_float_label_edit_text.xml index 180374aea..a0c2010c8 100644 --- a/app/src/main/res/layout/widget_float_label_edit_text.xml +++ b/app/src/main/res/layout/widget_float_label_edit_text.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml new file mode 100644 index 000000000..b15e63f67 --- /dev/null +++ b/app/src/main/res/values-land/dimens.xml @@ -0,0 +1,22 @@ + + + + + + 4dp + 4dp + + diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 000000000..efee43af8 --- /dev/null +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,23 @@ + + + + + + + 16dp + 24dp + + diff --git a/app/src/main/res/values-sw720dp/dimens.xml b/app/src/main/res/values-sw720dp/dimens.xml index f9795f702..b16d180b2 100644 --- a/app/src/main/res/values-sw720dp/dimens.xml +++ b/app/src/main/res/values-sw720dp/dimens.xml @@ -20,4 +20,8 @@ 80dp 80dp + + 24dp + 24dp + diff --git a/app/src/main/res/values-v19/themes.xml b/app/src/main/res/values-v19/themes.xml index 84942fa0f..edc5c162f 100644 --- a/app/src/main/res/values-v19/themes.xml +++ b/app/src/main/res/values-v19/themes.xml @@ -21,4 +21,9 @@ true + + diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml new file mode 100644 index 000000000..5fc0ed4ab --- /dev/null +++ b/app/src/main/res/values-v21/themes.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..d505a5941 --- /dev/null +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,28 @@ + + + + + + + 常规选项 + 高级选项 + 标签搜索 + 图片搜索 + 指定上传者 + 启用高级选项 + 没关键字也行 + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 59cf00765..301e9b968 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -55,8 +55,10 @@ #ffeeeeee #ffe1e1e0 - @color/material_teal_500 - @color/material_teal_700 - #ffff6977 + @color/material_teal_500 + @color/material_teal_700 + #ffff6977 + + @android:color/white diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 7b521cf02..fabd68bbb 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -21,4 +21,18 @@ 0dp 0dp + + 0dp + 0dp + + + 4dp + + + 48dp + + + 16dp + 16dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6ca3cc22..4d5c7001c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,4 +33,13 @@ MISC UNKNOWN + + Normal + Advance + Tag + Image + Specify Uploader + Enable advance options + No keyword is OK + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c35570635..2cb04f192 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -15,6 +15,14 @@ --> + + + + + +