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 37d7163b6..077ae4377 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java @@ -28,7 +28,7 @@ import android.widget.AdapterView; import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; import com.hippo.ehviewer.ui.scene.GalleryListScene; -import com.hippo.ehviewer.ui.scene.SettingsHeaderScene; +import com.hippo.ehviewer.ui.scene.MainSettingsScene; import com.hippo.ehviewer.ui.scene.SignInScene; import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.widget.DrawerLeftPanel; @@ -86,7 +86,7 @@ public final class ContentActivity extends StageActivity break; case DRAWER_LIST_SETTINGS: mDrawerLayout.closeDrawers(); - startScene(SettingsHeaderScene.class, null, new SimpleCurtain(SimpleCurtain.DIRECTION_BOTTOM)); + startScene(MainSettingsScene.class, null, new SimpleCurtain(SimpleCurtain.DIRECTION_BOTTOM)); break; } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DisplaySettingsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/DisplaySettingsScene.java new file mode 100644 index 000000000..657284949 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DisplaySettingsScene.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.ehviewer.ui.scene; + +import android.content.res.Resources; +import android.os.Bundle; + +import com.hippo.ehviewer.R; +import com.hippo.scene.preference.DialogPreference; +import com.hippo.scene.preference.Preference; +import com.hippo.scene.preference.PreferenceCategory; +import com.hippo.scene.preference.PreferenceScene; +import com.hippo.scene.preference.PreferenceSet; +import com.hippo.scene.preference.SwitchPreference; + +public class DisplaySettingsScene extends PreferenceScene { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTitle(R.string.settings); + setIcon(R.drawable.ic_arrow_left_dark); + + setPreferenceSet(getPreferenceSet()); + } + + private PreferenceSet[] getPreferenceSet() { + Resources resources = getStageActivity().getResources(); + + PreferenceSet preferenceSet = new PreferenceSet(); + preferenceSet.setPreferenceCategory(new PreferenceCategory("Display")); + + Preference[] preferences = new Preference[] { + new SwitchPreference("custom_theme_color", "屏幕方向", "速度速度速度速度加快"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地"), + new DialogPreference("sssss", "ssssssssss", "sssssssssss"), + new Preference("fdfdfdf", "哈哈哈", "恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地恩雅咋地") + }; + + preferenceSet.setPreferenceList(preferences); + + return new PreferenceSet[] { + preferenceSet + }; + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index 8cf74a111..42579b2b3 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -153,8 +153,8 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, } }; - private SimpleDialog.OnButtonClickListener mGoToButtonClickListener = - new SimpleDialog.OnButtonClickListener() { + private SimpleDialog.OnClickListener mGoToButtonClickListener = + new SimpleDialog.OnClickListener() { @Override public boolean onClick(SimpleDialog dialog, int which) { if (which == SimpleDialog.POSITIVE) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/MainSettingsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/MainSettingsScene.java new file mode 100644 index 000000000..a91d26a1e --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/MainSettingsScene.java @@ -0,0 +1,55 @@ +/* + * 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.ui.scene; + +import android.content.res.Resources; +import android.os.Bundle; + +import com.hippo.ehviewer.R; +import com.hippo.scene.preference.PreferenceHeader; +import com.hippo.scene.preference.PreferenceHeaderScene; + +public final class MainSettingsScene extends PreferenceHeaderScene { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTitle(R.string.settings); + setIcon(R.drawable.ic_arrow_left_dark); + + Resources resources = getStageActivity().getResources(); + + PreferenceHeader[] phs = new PreferenceHeader[] { + new PreferenceHeader( + resources.getDrawable(R.drawable.ic_cellphone_android_theme_primary), + resources.getString(R.string.display), + DisplaySettingsScene.class + ), + new PreferenceHeader( + resources.getDrawable(R.drawable.ic_eh_theme_primary), + resources.getString(R.string.eh), + null + ) + }; + setPreferenceHeaders(phs); + } + + @Override + public void onIconClick() { + finish(); + } +} diff --git a/app/src/main/java/com/hippo/scene/Curtain.java b/app/src/main/java/com/hippo/scene/Curtain.java index eb6fcd4fc..f45b79370 100644 --- a/app/src/main/java/com/hippo/scene/Curtain.java +++ b/app/src/main/java/com/hippo/scene/Curtain.java @@ -37,6 +37,9 @@ public abstract class Curtain { return scene != null && scene.getId() == mPreviousSceneId; } + protected void onReplace() { + } + /** * Called when * diff --git a/app/src/main/java/com/hippo/scene/Scene.java b/app/src/main/java/com/hippo/scene/Scene.java index d43a12760..5d17a3144 100644 --- a/app/src/main/java/com/hippo/scene/Scene.java +++ b/app/src/main/java/com/hippo/scene/Scene.java @@ -263,6 +263,9 @@ public abstract class Scene { mId = oldScene.mId; mAnnouncer = oldScene.mAnnouncer; mCurtain = oldScene.mCurtain; + if (mCurtain != null) { + mCurtain.onReplace(); + } } protected void onNewAnnouncer(Announcer announcer) { @@ -383,7 +386,7 @@ public abstract class Scene { return getStateKey() + ":gone"; } - void saveInstanceState(Bundle outState) { + protected void saveInstanceState(Bundle outState) { SparseArray states = new SparseArray<>(); onSaveInstanceState(states); outState.putSparseParcelableArray(getStateKey(), states); @@ -393,7 +396,7 @@ public abstract class Scene { } } - void restoreInstanceState(@NonNull Bundle savedInstanceState) { + protected void restoreInstanceState(@NonNull Bundle savedInstanceState) { if (mSceneView != null) { SparseArray savedStates = savedInstanceState.getSparseParcelableArray(getStateKey()); diff --git a/app/src/main/java/com/hippo/scene/SceneDialogView.java b/app/src/main/java/com/hippo/scene/SceneDialogView.java index 09ed39446..57f61a168 100644 --- a/app/src/main/java/com/hippo/scene/SceneDialogView.java +++ b/app/src/main/java/com/hippo/scene/SceneDialogView.java @@ -74,11 +74,11 @@ public class SceneDialogView extends SceneView implements View.OnClickListener, public void onClick(View v) { if (v == this && !ViewUtils.isViewUnder(getChildAt(0), (int) mHostpotX, (int) mHostpotY) && mOnClickOutOfDialogListener != null) { - mOnClickOutOfDialogListener.onClickOutOfDialog(); + mOnClickOutOfDialogListener.onClickOutOfDialog((int) mHostpotX, (int) mHostpotY); } } public interface OnClickOutOfDialogListener { - void onClickOutOfDialog(); + void onClickOutOfDialog(int x, int y); } } diff --git a/app/src/main/java/com/hippo/scene/SceneView.java b/app/src/main/java/com/hippo/scene/SceneView.java index f46be31bf..e936d77c2 100644 --- a/app/src/main/java/com/hippo/scene/SceneView.java +++ b/app/src/main/java/com/hippo/scene/SceneView.java @@ -58,4 +58,9 @@ public class SceneView extends AbsoluteLayout { public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { return mEnableTouch && super.dispatchTouchEvent(ev); } + + @Override + public boolean dispatchGenericMotionEvent(@NonNull MotionEvent event) { + return mEnableTouch && super.dispatchGenericMotionEvent(event); + } } diff --git a/app/src/main/java/com/hippo/scene/SimpleDialog.java b/app/src/main/java/com/hippo/scene/SimpleDialog.java index 646962f86..88e02b040 100644 --- a/app/src/main/java/com/hippo/scene/SimpleDialog.java +++ b/app/src/main/java/com/hippo/scene/SimpleDialog.java @@ -22,18 +22,21 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.FrameLayout; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.ScrollView; import android.widget.Space; import android.widget.TextView; import com.hippo.effect.ripple.RippleSalon; import com.hippo.ehviewer.R; import com.hippo.util.ViewUtils; -import com.hippo.widget.IndicatingScrollView; -// TODO Update start point after screen direction change public class SimpleDialog extends SceneDialog implements View.OnClickListener, - SceneDialogView.OnClickOutOfDialogListener { + SceneDialogView.OnClickOutOfDialogListener, AdapterView.OnItemClickListener { private static final int BACKGROUND_COLOR = 0x8a000000; @@ -47,9 +50,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, private View mBody; private TextView mTitle; private Space mSpaceTitleContent; - private IndicatingScrollView mContent; + private ScrollView mContent; private TextView mMessage; private FrameLayout mCustom; + private ListView mListView; private View mButtonsSingleLine; private TextView mNegativeButton; private View mSpacePositiveNegative; @@ -77,9 +81,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, mBody = findViewById(R.id.body); mTitle = (TextView) mBody.findViewById(R.id.title); mSpaceTitleContent = (Space) mBody.findViewById(R.id.space_title_content); - mContent = (IndicatingScrollView) findViewById(R.id.content); + mContent = (ScrollView) findViewById(R.id.content); mMessage = (TextView) mBody.findViewById(R.id.message); mCustom = (FrameLayout) mBody.findViewById(R.id.custom); + mListView = (ListView) mBody.findViewById(R.id.list); mButtonsSingleLine = findViewById(R.id.buttons_single_line); mNegativeButton = (TextView) mButtonsSingleLine.findViewById(R.id.negative); mSpacePositiveNegative = mButtonsSingleLine.findViewById(R.id.space_positive_negative); @@ -99,6 +104,9 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, } private void bindDialog() { + ListView listView = mListView; + + if (mBuilder.mTitle == null && mBuilder.mMessage == null && mBuilder.mCustomViewResId == 0) { ViewUtils.setVisibility(mBody, View.GONE); } else { @@ -111,6 +119,19 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, if (mBuilder.mMessage != null) { mMessage.setText(mBuilder.mMessage); + ViewUtils.setVisibility(mListView, View.GONE); + ViewUtils.setVisibility(mCustom, View.GONE); + } else if (mBuilder.mAdapter != null) { + listView.setAdapter(mBuilder.mAdapter); + listView.setOnItemClickListener(this); + if (mBuilder.mIsSingleChoice) { + listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + if (mBuilder.mCheckedItem > -1) { + listView.setItemChecked(mBuilder.mCheckedItem, true); + listView.setSelection(mBuilder.mCheckedItem); + } + } + ViewUtils.setVisibility(mContent, View.GONE); ViewUtils.setVisibility(mCustom, View.GONE); } else if (mBuilder.mCustomViewResId != 0) { getStageActivity().getLayoutInflater().inflate(mBuilder.mCustomViewResId, mCustom); @@ -119,8 +140,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, mCustom.getChildAt(0)); } ViewUtils.setVisibility(mContent, View.GONE); + ViewUtils.setVisibility(mListView, View.GONE); } else { ViewUtils.setVisibility(mContent, View.GONE); + ViewUtils.setVisibility(mListView, View.GONE); ViewUtils.setVisibility(mCustom, View.GONE); ViewUtils.setVisibility(mSpaceTitleContent, View.GONE); } @@ -225,8 +248,22 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, } @Override - public void onClickOutOfDialog() { + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (parent == mListView) { + OnClickListener listener = mBuilder.mOnListItemClickListener; + if (listener == null || listener.onClick(this, position)) { + finish(); + } + } + } + + @Override + public void onClickOutOfDialog(int x, int y) { if (mBuilder.mCancelable) { + Curtain curtain = getCurtain(); + if (curtain instanceof SimpleDialogCurtain) { + ((SimpleDialogCurtain) curtain).setStartPosition(x, y); + } finish(); } } @@ -237,11 +274,18 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, private String mTitle; private String mMessage; + + private ListAdapter mAdapter; + private OnClickListener mOnListItemClickListener; + protected int mCheckedItem; + protected boolean mIsSingleChoice; + private int mCustomViewResId = 0; private OnCreateCustomViewListener mOnCreateCustomViewListener; + private String mPositiveButtonText; private String mNegativeButtonText; - private OnButtonClickListener mOnButtonClickListener; + private OnClickListener mOnButtonClickListener; private boolean mCancelable = true; @@ -270,6 +314,61 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, return setMessage(mContext.getString(resId)); } + public Builder setItems(int itemsId, final OnClickListener listener) { + mAdapter = new ArrayAdapter<>(mContext, R.layout.select_dialog_item, + android.R.id.text1, mContext.getResources().getTextArray(itemsId)); + mOnListItemClickListener = listener; + mIsSingleChoice = false; + return this; + } + + public Builder setItems(CharSequence[] items, + final OnClickListener listener) { + mAdapter = new ArrayAdapter<>(mContext, R.layout.select_dialog_item, + android.R.id.text1, items); + mOnListItemClickListener = listener; + mIsSingleChoice = false; + return this; + } + + public Builder setAdapter(final ListAdapter adapter, + final OnClickListener listener) { + mAdapter = adapter; + mOnListItemClickListener = listener; + mIsSingleChoice = false; + return this; + } + + public Builder setSingleChoiceItems(int itemsId, int checkedItem, + final OnClickListener listener) { + mAdapter = new ArrayAdapter<>(mContext, + R.layout.select_dialog_singlechoice, android.R.id.text1, + mContext.getResources().getTextArray(itemsId)); + mOnListItemClickListener = listener; + mCheckedItem = checkedItem; + mIsSingleChoice = true; + return this; + } + + public Builder setSingleChoiceItems(CharSequence[] items, + int checkedItem, final OnClickListener listener) { + mAdapter = new ArrayAdapter(mContext, + R.layout.select_dialog_singlechoice, android.R.id.text1, items); + mOnListItemClickListener = listener; + mCheckedItem = checkedItem; + mIsSingleChoice = true; + return this; + } + + public Builder setSingleChoiceItems(ListAdapter adapter, + int checkedItem, final OnClickListener listener) { + mAdapter = adapter; + mOnListItemClickListener = listener; + mCheckedItem = checkedItem; + mIsSingleChoice = true; + return this; + } + public Builder setCustomView(@LayoutRes int resId, @Nullable OnCreateCustomViewListener listener) { mCustomViewResId = resId; @@ -295,7 +394,7 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, return setNegativeButton(mContext.getString(resId)); } - public Builder setOnButtonClickListener(OnButtonClickListener listener) { + public Builder setOnButtonClickListener(OnClickListener listener) { mOnButtonClickListener = listener; return this; } @@ -333,7 +432,12 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener, void onCreateCustomView(SimpleDialog dialog, View view); } - public interface OnButtonClickListener { + public interface OnClickListener { boolean onClick(SimpleDialog dialog, int which); } + + // TODO + public interface OnCloseListener { + void onClose(); + } } diff --git a/app/src/main/java/com/hippo/scene/SimpleDialogCurtain.java b/app/src/main/java/com/hippo/scene/SimpleDialogCurtain.java index 6e0799e30..77a588905 100644 --- a/app/src/main/java/com/hippo/scene/SimpleDialogCurtain.java +++ b/app/src/main/java/com/hippo/scene/SimpleDialogCurtain.java @@ -50,6 +50,17 @@ public class SimpleDialogCurtain extends Curtain { mStartY = startY; } + public void setStartPosition(int startX, int startY) { + mStartX = startX; + mStartY = startY; + } + + @Override + protected void onReplace() { + mStartX = 0; + mStartY = 0; + } + @Override public void open(@NonNull final Scene enter, @NonNull final Scene exit) { AssertUtils.assertInstanceof("SimpleDialogCurtain should only use for SimpleDialog.", enter, SimpleDialog.class); diff --git a/app/src/main/java/com/hippo/scene/SimpleDialogFrame.java b/app/src/main/java/com/hippo/scene/SimpleDialogFrame.java index f13174024..f47409e6b 100644 --- a/app/src/main/java/com/hippo/scene/SimpleDialogFrame.java +++ b/app/src/main/java/com/hippo/scene/SimpleDialogFrame.java @@ -19,6 +19,7 @@ import android.content.Context; import android.content.res.Resources; import android.support.v7.widget.CardView; import android.util.AttributeSet; +import android.view.RenderNodeAnimator; import android.widget.AbsoluteLayout; import com.hippo.ehviewer.R; @@ -110,6 +111,7 @@ public class SimpleDialogFrame extends CardView { mDrawLeft = drawLeft; setLeft(drawLeft); setScrollX(drawLeft - mOriginLeft); + RenderNodeAnimator animato; } @SuppressWarnings("unused") diff --git a/app/src/main/java/com/hippo/scene/preference/DialogPreference.java b/app/src/main/java/com/hippo/scene/preference/DialogPreference.java new file mode 100644 index 000000000..31f359b69 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/DialogPreference.java @@ -0,0 +1,24 @@ +package com.hippo.scene.preference; + +import android.support.v7.widget.RecyclerView; + +import com.hippo.scene.SimpleDialog; + +public class DialogPreference extends Preference { + + public DialogPreference(String key, String title, String summary) { + super(key, title, summary); + } + + @Override + public boolean onClick(RecyclerView.ViewHolder viewHolder, int x, int y) { + if (!super.onClick(viewHolder, x, y)) { + SimpleDialog.Builder builder = new SimpleDialog.Builder(viewHolder.itemView.getContext()); + builder.setTitle("Title"); + builder.setSingleChoiceItems(new CharSequence[]{"横向", "竖向", "斜向"}, 0, null); + builder.setStartPoint(x, y); + builder.show(); + } + return true; + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/Preference.java b/app/src/main/java/com/hippo/scene/preference/Preference.java new file mode 100644 index 000000000..10c5b0bec --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/Preference.java @@ -0,0 +1,105 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.hippo.ehviewer.R; + +public class Preference extends PreferenceBase { + + private String mKey; + private String mTitle; + private String mSummary; + + private OnClickListener mOnClickListener; + + public Preference(String key, String title, String summary) { + mKey = key; + mTitle = title; + mSummary = summary; + } + + public String getKey() { + return mKey; + } + + @Override + int getItemViewType() { + return PreferenceCenter.TYPE_PEFERENCE; + } + + public static RecyclerView.ViewHolder createViewHolder(Context content, ViewGroup parent) { + return new PreferenceHolder(LayoutInflater.from(content).inflate(R.layout.preference, parent, false)); + } + + @Override + void bindViewHolde(Context context, RecyclerView.ViewHolder viewHolder) { + PreferenceHolder pvh = (PreferenceHolder) viewHolder; + pvh.title.setText(mTitle); + pvh.summary.setText(mSummary); + if (!stableWidgetFrame() || !pvh.hasSetWidgetFrame) { + pvh.widgetFrame.removeAllViews(); + onBind(context, pvh.widgetFrame); + pvh.hasSetWidgetFrame = true; + } + + onUpdateView(viewHolder); + } + + protected void onBind(Context context, FrameLayout widgetFrame) { + } + + protected void onUpdateView(RecyclerView.ViewHolder viewHolder) { + } + + @Override + public boolean onClick(RecyclerView.ViewHolder viewHolder, int x, int y) { + return mOnClickListener != null && mOnClickListener.onClick(); + } + + protected boolean stableWidgetFrame() { + return false; + } + + public String getSummary() { + return mSummary; + } + + public void setSummary(String summary) { + mSummary = summary; + } + + public String getTitle() { + return mTitle; + } + + public void setTitle(String title) { + mTitle = title; + } + + public void setOnClickListener(OnClickListener listener) { + mOnClickListener = listener; + } + + public interface OnClickListener { + boolean onClick(); + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceBase.java b/app/src/main/java/com/hippo/scene/preference/PreferenceBase.java new file mode 100644 index 000000000..c53af1bb8 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceBase.java @@ -0,0 +1,36 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; + +abstract class PreferenceBase { + + abstract int getItemViewType(); + + abstract void bindViewHolde(Context context, RecyclerView.ViewHolder viewHolder); + + /** + * @param viewHolder the view holder of the view + * @param x x position in scene + * @param y y position in scene + * @return true if handle the click action + */ + public boolean onClick(RecyclerView.ViewHolder viewHolder, int x, int y) { + return false; + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceCategory.java b/app/src/main/java/com/hippo/scene/preference/PreferenceCategory.java new file mode 100644 index 000000000..d3d76cb82 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceCategory.java @@ -0,0 +1,56 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import com.hippo.ehviewer.R; + +public class PreferenceCategory extends PreferenceBase { + + private String mTitle; + + public PreferenceCategory(String title) { + mTitle = title; + } + + @Override + int getItemViewType() { + return PreferenceCenter.TYPE_PEFERENCE_CATEGORY; + } + + public static RecyclerView.ViewHolder createViewHolder(Context content, ViewGroup parent) { + return new PreferenceCategoryHolder(LayoutInflater.from(content) + .inflate(R.layout.preference_category, parent, false)); + } + + @Override + void bindViewHolde(Context context, RecyclerView.ViewHolder viewHolder) { + PreferenceCategoryHolder pvh = (PreferenceCategoryHolder) viewHolder; + pvh.title.setText(mTitle); + } + + public String getTitle() { + return mTitle; + } + + public void setTitle(String title) { + mTitle = title; + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceCategoryHolder.java b/app/src/main/java/com/hippo/scene/preference/PreferenceCategoryHolder.java new file mode 100644 index 000000000..20432892d --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceCategoryHolder.java @@ -0,0 +1,31 @@ +/* + * 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.scene.preference; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; + +public class PreferenceCategoryHolder extends RecyclerView.ViewHolder { + + public TextView title; + + public PreferenceCategoryHolder(View itemView) { + super(itemView); + + title = (TextView) itemView; + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceCenter.java b/app/src/main/java/com/hippo/scene/preference/PreferenceCenter.java new file mode 100644 index 000000000..232aa6be7 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceCenter.java @@ -0,0 +1,70 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.util.SparseArray; +import android.view.ViewGroup; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public final class PreferenceCenter { + + static final int TYPE_PEFERENCE_DIVIDER = 0; + static final int TYPE_PEFERENCE_CATEGORY = 1; + static final int TYPE_PEFERENCE = 2; + static final int TYPE_SWITCH_PEFERENCE = 3; + static final int TYPE_DIALOG_PEFERENCE = 4; + + static SparseArray mMethodArray = new SparseArray<>(); + + static { + register(TYPE_PEFERENCE_DIVIDER, PreferenceDivider.class); + register(TYPE_PEFERENCE_CATEGORY, PreferenceCategory.class); + register(TYPE_PEFERENCE, Preference.class); + register(TYPE_SWITCH_PEFERENCE, SwitchPreference.class); + register(TYPE_DIALOG_PEFERENCE, DialogPreference.class); + } + + @SuppressWarnings("unchecked") + public static void register(int type, Class clazz) { + try { + Method method = clazz.getMethod("createViewHolder", Context.class, ViewGroup.class); + mMethodArray.append(type, method); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new IllegalStateException(e); + } + } + + @SuppressWarnings("TryWithIdenticalCatches") + public static RecyclerView.ViewHolder createViewHolder(int type, Context content, ViewGroup parent) { + Method method = mMethodArray.get(type); + if (method == null) { + throw new IllegalStateException("You must register for type " + type); + } + + try { + return (RecyclerView.ViewHolder) method.invoke(null, content, parent); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (InvocationTargetException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceDivider.java b/app/src/main/java/com/hippo/scene/preference/PreferenceDivider.java new file mode 100644 index 000000000..791f16e30 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceDivider.java @@ -0,0 +1,42 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import com.hippo.ehviewer.R; +import com.hippo.widget.recyclerview.SimpleHolder; + +public class PreferenceDivider extends PreferenceBase { + + @Override + int getItemViewType() { + return PreferenceCenter.TYPE_PEFERENCE_DIVIDER; + } + + public static RecyclerView.ViewHolder createViewHolder(Context content, ViewGroup parent) { + return new SimpleHolder(LayoutInflater.from(content) + .inflate(R.layout.preference_divider, parent, false)); + } + + @Override + void bindViewHolde(Context context, RecyclerView.ViewHolder viewHolder) { + // Empty + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceHeader.java b/app/src/main/java/com/hippo/scene/preference/PreferenceHeader.java new file mode 100644 index 000000000..2915e8d0e --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceHeader.java @@ -0,0 +1,55 @@ +/* + * 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.scene.preference; + +import android.graphics.drawable.Drawable; + +public class PreferenceHeader { + + private Drawable mIcon; + private String mTitle; + private Class mPreferenceClazz; + + public PreferenceHeader(Drawable icon, String title, Class preferenceClazz) { + mIcon = icon; + mTitle = title; + mPreferenceClazz = preferenceClazz; + } + + public Drawable getIcon() { + return mIcon; + } + + public void setIcon(Drawable icon) { + mIcon = icon; + } + + public String getTitle() { + return mTitle; + } + + public void setTitle(String title) { + mTitle = title; + } + + public Class getPreferenceClazz() { + return mPreferenceClazz; + } + + public void setPreferenceClazz(Class preferenceClazz) { + mPreferenceClazz = preferenceClazz; + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SettingsHeaderScene.java b/app/src/main/java/com/hippo/scene/preference/PreferenceHeaderScene.java similarity index 62% rename from app/src/main/java/com/hippo/ehviewer/ui/scene/SettingsHeaderScene.java rename to app/src/main/java/com/hippo/scene/preference/PreferenceHeaderScene.java index 133fc05f1..b8e3eddec 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SettingsHeaderScene.java +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceHeaderScene.java @@ -13,8 +13,9 @@ * limitations under the License. */ -package com.hippo.ehviewer.ui.scene; +package com.hippo.scene.preference; +import android.annotation.NonNull; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -27,41 +28,50 @@ import android.widget.TextView; import com.hippo.effect.ripple.RippleSalon; import com.hippo.ehviewer.R; import com.hippo.scene.AppbarScene; +import com.hippo.scene.SimpleCurtain; import com.hippo.scene.StageActivity; import com.hippo.util.ViewUtils; import com.hippo.widget.recyclerview.EasyRecyclerView; -public final class SettingsHeaderScene extends AppbarScene implements EasyRecyclerView.OnItemClickListener { +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; - private static final int[] HEADER_ICON_ARRAY = { - R.drawable.ic_cellphone_android_theme_primary, - R.drawable.ic_eh_theme_primary - }; - - private static final int[] HEADER_TITLE_ARRAY = { - R.string._goto, - R.string.username - }; +public class PreferenceHeaderScene extends AppbarScene { private StageActivity mActivity; private EasyRecyclerView mRecyclerView; + private HeaderAdapter mHeaderAdapter; + + private List mHeaderList = new ArrayList<>(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mActivity = getStageActivity(); - setTitle(R.string.signout); - setIcon(R.drawable.ic_arrow_left_dark); - mRecyclerView = new EasyRecyclerView(mActivity); + mRecyclerView = new EasyRecyclerView(getStageActivity()); setContentView(mRecyclerView); - mRecyclerView.setAdapter(new HeaderAdapter()); + mHeaderAdapter = new HeaderAdapter(); + mRecyclerView.setAdapter(mHeaderAdapter); mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity, LinearLayoutManager.VERTICAL, false)); mRecyclerView.setClipToPadding(false); - mRecyclerView.setOnItemClickListener(this); + mRecyclerView.setOnItemClickListener(new EasyRecyclerView.OnItemClickListener() { + @Override + public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) { + Class clazz = mHeaderList.get(position).getPreferenceClazz(); + if (clazz == null) { + return false; + } else { + startScene(clazz, null, new SimpleCurtain(SimpleCurtain.DIRECTION_BOTTOM)); + return true; + } + } + }); mRecyclerView.setSelector(RippleSalon.generateRippleDrawable(mActivity, false)); } @@ -72,14 +82,10 @@ public final class SettingsHeaderScene extends AppbarScene implements EasyRecycl mRecyclerView.getPaddingRight(), b); } - @Override - public void onIconClick() { - finish(); - } - - @Override - public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) { - return false; + public void setPreferenceHeaders(@NonNull PreferenceHeader[] preferenceHeaders) { + mHeaderList.clear(); + Collections.addAll(mHeaderList, preferenceHeaders); + mHeaderAdapter.notifyDataSetChanged(); } private static class HeaderHolder extends RecyclerView.ViewHolder { @@ -101,21 +107,20 @@ public final class SettingsHeaderScene extends AppbarScene implements EasyRecycl @Override public HeaderHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(mActivity).inflate(R.layout.settings_header, parent, false); + View view = LayoutInflater.from(mActivity).inflate(R.layout.preference_header, parent, false); return new HeaderHolder(view); } @Override public void onBindViewHolder(HeaderHolder holder, int position) { - holder.icon.setImageResource(HEADER_ICON_ARRAY[position]); - holder.title.setText(HEADER_TITLE_ARRAY[position]); - ViewUtils.setVisibility(holder.tileDivider, - position == getItemCount() - 1 ? View.INVISIBLE : View.VISIBLE); + holder.icon.setImageDrawable(mHeaderList.get(position).getIcon()); + holder.title.setText(mHeaderList.get(position).getTitle()); + ViewUtils.setVisibility(holder.tileDivider, position == getItemCount() - 1 ? View.INVISIBLE : View.VISIBLE); } @Override public int getItemCount() { - return HEADER_ICON_ARRAY.length; + return mHeaderList.size(); } } } diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceHolder.java b/app/src/main/java/com/hippo/scene/preference/PreferenceHolder.java new file mode 100644 index 000000000..42ef922b2 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceHolder.java @@ -0,0 +1,39 @@ +/* + * 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.scene.preference; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import com.hippo.ehviewer.R; + +public class PreferenceHolder extends RecyclerView.ViewHolder { + + public TextView title; + public TextView summary; + public FrameLayout widgetFrame; + public boolean hasSetWidgetFrame; + + public PreferenceHolder(View itemView) { + super(itemView); + + title = (TextView) itemView.findViewById(R.id.title); + summary = (TextView) itemView.findViewById(R.id.summary); + widgetFrame = (FrameLayout) itemView.findViewById(R.id.widget_frame); + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceScene.java b/app/src/main/java/com/hippo/scene/preference/PreferenceScene.java new file mode 100644 index 000000000..30e2c7785 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceScene.java @@ -0,0 +1,136 @@ +/* + * 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.scene.preference; + +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; + +import com.hippo.effect.ripple.RippleSalon; +import com.hippo.ehviewer.R; +import com.hippo.scene.AppbarScene; +import com.hippo.util.ViewUtils; +import com.hippo.widget.recyclerview.EasyRecyclerView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PreferenceScene extends AppbarScene { + + private static PreferenceDivider PREFERENCE_DIVIDER = new PreferenceDivider(); + + private EasyRecyclerView mRecyclerView; + + private PreferenceAdapter mAdapter; + + private List mPreferenceSetList = new ArrayList<>(); + private List mPreferenceBaseList = new ArrayList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mRecyclerView = new EasyRecyclerView(getStageActivity()); + setContentView(mRecyclerView); + + mAdapter = new PreferenceAdapter(); + mRecyclerView.setAdapter(mAdapter); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getStageActivity())); + mRecyclerView.setOnItemClickListener(new PreferenceItemClickListener()); + mRecyclerView.setSelector(RippleSalon.generateRippleDrawable(getStageActivity(), false)); + mRecyclerView.setOnDrawSelectorListener(new PreferencesDrawSelectorListener()); + mRecyclerView.setClipToPadding(false); + } + + @Override + protected void onGetFitPaddingBottom(int b) { + mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), + mRecyclerView.getPaddingTop(), + mRecyclerView.getPaddingRight(), b); + } + + public void setPreferenceSet(PreferenceSet[] preferenceSets) { + // Update mPreferenceSetList + List preferenceSetList = mPreferenceSetList; + preferenceSetList.clear(); + Collections.addAll(preferenceSetList, preferenceSets); + // Update mPreferenceBasesList + List preferenceBaseList = mPreferenceBaseList; + preferenceBaseList.clear(); + for (PreferenceSet ps : preferenceSets) { + PreferenceCategory pc = ps.getPreferenceCategory(); + if (pc != null) { + preferenceBaseList.add(pc); + } + int pdCount = ps.getPreferenceCount(); + for (int i = 0; i < pdCount; i++) { + if (i != 0) { + preferenceBaseList.add(PREFERENCE_DIVIDER); + } + preferenceBaseList.add(ps.getPreferenceData(i)); + } + } + mAdapter.notifyDataSetChanged(); + } + + private class PreferenceAdapter extends RecyclerView.Adapter { + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return PreferenceCenter.createViewHolder(viewType, getStageActivity(), parent); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + mPreferenceBaseList.get(position).bindViewHolde(getStageActivity(), holder); + } + + @Override + public int getItemCount() { + return mPreferenceBaseList.size(); + } + + @Override + public int getItemViewType(int position) { + return mPreferenceBaseList.get(position).getItemViewType(); + } + } + + private class PreferenceItemClickListener implements EasyRecyclerView.OnItemClickListener { + + private int[] mTemp = new int[2]; + + @Override + public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) { + ViewUtils.getLocationInAncestor(parent, mTemp, R.id.stage); + return mPreferenceBaseList.get(position).onClick(parent.getChildViewHolder(view), + (int) (mTemp[0] + parent.getTouchStartX()), + (int) (mTemp[1] + parent.getTouchStartY())); + } + } + + private class PreferencesDrawSelectorListener implements EasyRecyclerView.OnDrawSelectorListener { + @Override + public boolean beforeDrawSelector(int position) { + PreferenceBase pb = mPreferenceBaseList.get(position); + return !(pb instanceof PreferenceCategory) && + !(pb instanceof PreferenceDivider); + } + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/PreferenceSet.java b/app/src/main/java/com/hippo/scene/preference/PreferenceSet.java new file mode 100644 index 000000000..0a9cf7db7 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/PreferenceSet.java @@ -0,0 +1,51 @@ +/* + * 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.scene.preference; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PreferenceSet { + + private PreferenceCategory mPreferenceCategory; + private List mPreferenceList = new ArrayList<>(); + + public PreferenceCategory getPreferenceCategory() { + return mPreferenceCategory; + } + + public void setPreferenceCategory(PreferenceCategory preferenceCategoryData) { + mPreferenceCategory = preferenceCategoryData; + } + + public Preference getPreferenceData(int position) { + return mPreferenceList.get(position); + } + + public int getPreferenceCount() { + return mPreferenceList.size(); + } + + public void setPreferenceList(Preference[] preferences) { + mPreferenceList.clear(); + Collections.addAll(mPreferenceList, preferences); + } + + public int getItemCount() { + return mPreferenceCategory == null ? 0 : 1 + mPreferenceList.size(); + } +} diff --git a/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java b/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java new file mode 100644 index 000000000..60a51d241 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java @@ -0,0 +1,72 @@ +/* + * 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.scene.preference; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SwitchCompat; +import android.view.LayoutInflater; +import android.widget.FrameLayout; + +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.util.Config; + +public class SwitchPreference extends Preference { + + private boolean mDefaultValue; + + public SwitchPreference(String key, String title, String summary) { + super(key, title, summary); + } + + public void setDefaultValue(boolean defaultValue) { + mDefaultValue = defaultValue; + } + + @Override + int getItemViewType() { + return PreferenceCenter.TYPE_SWITCH_PEFERENCE; + } + + @Override + protected void onBind(Context context, FrameLayout widgetFrame) { + widgetFrame.removeAllViews(); + LayoutInflater.from(context).inflate(R.layout.widget_frame_switch_preference, widgetFrame); + } + + @Override + protected void onUpdateView(RecyclerView.ViewHolder viewHolder) { + PreferenceHolder pvh = (PreferenceHolder) viewHolder; + ((SwitchCompat) pvh.widgetFrame.getChildAt(0)) + .setChecked(Config.getBoolean(getKey(), mDefaultValue)); + } + + @Override + public boolean onClick(RecyclerView.ViewHolder viewHolder, int x, int y) { + if (!super.onClick(viewHolder, x, y)) { + PreferenceHolder pvh = (PreferenceHolder) viewHolder; + SwitchCompat switchCompat = (SwitchCompat) pvh.widgetFrame.getChildAt(0); + switchCompat.toggle(); + Config.putBoolean(getKey(), switchCompat.isChecked()); + } + return true; + } + + @Override + protected boolean stableWidgetFrame() { + return true; + } +} diff --git a/app/src/main/java/com/hippo/util/Utils.java b/app/src/main/java/com/hippo/util/Utils.java index 112618c2d..73e68f40c 100644 --- a/app/src/main/java/com/hippo/util/Utils.java +++ b/app/src/main/java/com/hippo/util/Utils.java @@ -239,19 +239,13 @@ public final class Utils { return Utils.parseIntSafely(DATE_FORMATE_FOR_UPDATE.format(new Date()), 0); } - - private static String[] SIZE_UNIT = {"%.2f B", "%.2f KB", "%.2f MB", "%.2f GB"}; - - public static String sizeToString(long size) { - int length = SIZE_UNIT.length; - - float sizeFloat = size; - for (int i = 0; i < length - 1; i++) { - if (sizeFloat < 1024) - return String.format(SIZE_UNIT[i], sizeFloat); - sizeFloat /= 1024; - } - return String.format(SIZE_UNIT[length - 1], sizeFloat); + // http://stackoverflow.com/questions/3758606/ + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) return bytes + " B"; + int exp = (int) (Math.log(bytes) / Math.log(unit)); + char pre = "KMGTPE".charAt(exp-1); + return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre); } /** diff --git a/app/src/main/java/com/hippo/widget/IndicatingListView.java b/app/src/main/java/com/hippo/widget/IndicatingListView.java new file mode 100644 index 000000000..853960cae --- /dev/null +++ b/app/src/main/java/com/hippo/widget/IndicatingListView.java @@ -0,0 +1,77 @@ +package com.hippo.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.widget.ListView; + +import com.hippo.ehviewer.R; + +public class IndicatingListView extends ListView { + + private int mIndicatorHeight; + + private Paint mPaint = new Paint(); + private Rect mTemp = new Rect(); + + public IndicatingListView(Context context) { + super(context); + init(context); + } + + public IndicatingListView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public IndicatingListView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + mIndicatorHeight = context.getResources().getDimensionPixelOffset(R.dimen.scroll_view_indicator_height); + mPaint.setColor(context.getResources().getColor(R.color.scroll_view_indicator)); + mPaint.setStyle(Paint.Style.FILL); + } + + private void fillTopIndicatorDrawRect() { + mTemp.set(0, 0, getWidth(), mIndicatorHeight); + } + + private void fillBottomIndicatorDrawRect() { + mTemp.set(0, getHeight() - mIndicatorHeight, getWidth(), getHeight()); + } + + private boolean needShowTopIndicator() { + return canScrollVertically(-1); + } + + private boolean needShowBottomIndicator() { + return canScrollVertically(1); + } + + @Override + public void draw(@NonNull Canvas canvas) { + super.draw(canvas); + + final int restoreCount = canvas.save(); + canvas.translate(getScrollX(), getScrollY()); + + // Draw top indicator + if (needShowTopIndicator()) { + fillTopIndicatorDrawRect(); + canvas.drawRect(mTemp, mPaint); + } + // Draw bottom indicator + if (needShowBottomIndicator()) { + fillBottomIndicatorDrawRect(); + canvas.drawRect(mTemp, mPaint); + } + + canvas.restoreToCount(restoreCount); + } +} diff --git a/app/src/main/java/com/hippo/widget/SimpleImageView.java b/app/src/main/java/com/hippo/widget/SimpleImageView.java index 0a6ce3a88..297a2d714 100644 --- a/app/src/main/java/com/hippo/widget/SimpleImageView.java +++ b/app/src/main/java/com/hippo/widget/SimpleImageView.java @@ -51,6 +51,7 @@ public class SimpleImageView extends View implements Drawable.Callback { setWillNotCacheDrawing(true); } + @SuppressWarnings("deprecation") public void setDrawable(@DrawableRes int resId) { setDrawable(getContext().getResources().getDrawable(resId)); } diff --git a/app/src/main/java/com/hippo/widget/SolidLinearLayout.java b/app/src/main/java/com/hippo/widget/SolidLinearLayout.java new file mode 100644 index 000000000..2dddfe7d9 --- /dev/null +++ b/app/src/main/java/com/hippo/widget/SolidLinearLayout.java @@ -0,0 +1,41 @@ +/* + * 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.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.LinearLayout; + +public class SolidLinearLayout extends LinearLayout { + + public SolidLinearLayout(Context context) { + super(context); + } + + public SolidLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SolidLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return true; + } +} diff --git a/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java b/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java index 6209dbf9f..2ee1a74da 100644 --- a/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java +++ b/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java @@ -166,6 +166,7 @@ public class EasyRecyclerView extends RecyclerView { */ int mSelectionBottomPadding = 0; + private OnDrawSelectorListener mOnDrawSelectorListener; public EasyRecyclerView(Context context) { super(context); @@ -278,14 +279,20 @@ public class EasyRecyclerView extends RecyclerView { mGroupFlags &= ~CLIP_TO_PADDING_MASK; } + // TODO disable selector drawable state change when need not to draw selector + boolean drawSelector = mOnDrawSelectorListener == null || + mSelectorPosition < 0 || + mSelectorPosition >= mAdapter.getItemCount() || + mOnDrawSelectorListener.beforeDrawSelector(mSelectorPosition); final boolean drawSelectorOnTop = mDrawSelectorOnTop; - if (!drawSelectorOnTop) { + + if (drawSelector && !drawSelectorOnTop) { drawSelector(canvas); } super.dispatchDraw(canvas); - if (drawSelectorOnTop) { + if (drawSelector && drawSelectorOnTop) { drawSelector(canvas); } @@ -314,6 +321,10 @@ public class EasyRecyclerView extends RecyclerView { } } + public void setOnDrawSelectorListener(OnDrawSelectorListener listener) { + mOnDrawSelectorListener = listener; + } + /** * Controls whether the selection highlight drawable should be drawn on top of the item or * behind it. @@ -351,6 +362,14 @@ public class EasyRecyclerView extends RecyclerView { return mSelector; } + private void cancelDrawingSelector() { + Rect rect = mSelectorRect; + rect.left = 0; + rect.top = 0; + rect.right = 0; + rect.bottom = 0; + } + void updateSelectorState() { if (mSelector != null) { if (shouldShowSelector()) { @@ -656,6 +675,14 @@ public class EasyRecyclerView extends RecyclerView { } } + public float getTouchStartX() { + return mStartX; + } + + public float getTouchStartY() { + return mStartY; + } + @Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { @@ -733,6 +760,7 @@ public class EasyRecyclerView extends RecyclerView { setPressed(false); } updateSelectorState(); + cancelDrawingSelector(); } } @@ -1215,6 +1243,19 @@ public class EasyRecyclerView extends RecyclerView { boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id); } + /** + * Interface definition for a callback to be invoked when draw selector. + */ + public interface OnDrawSelectorListener { + /** + * Callback method to be invoked before selector draw. + * + * @param position The EasyRecyclerView where the click happened + * @return true if need draw selector, false otherwise + */ + boolean beforeDrawSelector(int position); + } + /** * A MultiChoiceModeListener receives events for {@link android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL}. * It acts as the {@link android.support.v7.view.ActionMode.Callback} for the selection mode and also receives diff --git a/app/src/main/java/com/hippo/widget/recyclerview/SimpleHolder.java b/app/src/main/java/com/hippo/widget/recyclerview/SimpleHolder.java new file mode 100644 index 000000000..87ade42de --- /dev/null +++ b/app/src/main/java/com/hippo/widget/recyclerview/SimpleHolder.java @@ -0,0 +1,26 @@ +/* + * 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.recyclerview; + +import android.support.v7.widget.RecyclerView; +import android.view.View; + +public class SimpleHolder extends RecyclerView.ViewHolder { + + public SimpleHolder(View itemView) { + super(itemView); + } +} diff --git a/app/src/main/res/layout/preference.xml b/app/src/main/res/layout/preference.xml new file mode 100644 index 000000000..46229cbe3 --- /dev/null +++ b/app/src/main/res/layout/preference.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/preference_category.xml b/app/src/main/res/layout/preference_category.xml new file mode 100644 index 000000000..adce1364e --- /dev/null +++ b/app/src/main/res/layout/preference_category.xml @@ -0,0 +1,25 @@ + + + diff --git a/app/src/main/res/layout/preference_divider.xml b/app/src/main/res/layout/preference_divider.xml new file mode 100644 index 000000000..d49e29e7c --- /dev/null +++ b/app/src/main/res/layout/preference_divider.xml @@ -0,0 +1,20 @@ + + + diff --git a/app/src/main/res/layout/settings_header.xml b/app/src/main/res/layout/preference_header.xml similarity index 80% rename from app/src/main/res/layout/settings_header.xml rename to app/src/main/res/layout/preference_header.xml index fbdd05bf7..babbaef65 100644 --- a/app/src/main/res/layout/settings_header.xml +++ b/app/src/main/res/layout/preference_header.xml @@ -19,16 +19,18 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" - android:minHeight="@dimen/settings_header_minimum_height"> + android:minHeight="@dimen/preference_header_minimum_height" + android:orientation="horizontal"> + android:layout_marginLeft="@dimen/preference_header_image_margin_start" + android:layout_marginRight="@dimen/preference_header_image_margin_end" + tools:ignore="RtlHardcoded" + android:contentDescription="@null"/> + + + diff --git a/app/src/main/res/layout/select_dialog_singlechoice.xml b/app/src/main/res/layout/select_dialog_singlechoice.xml new file mode 100644 index 000000000..b8f9df8d1 --- /dev/null +++ b/app/src/main/res/layout/select_dialog_singlechoice.xml @@ -0,0 +1,28 @@ + + + diff --git a/app/src/main/res/layout/simple_dialog.xml b/app/src/main/res/layout/simple_dialog.xml index 6da7102de..d1b5986c2 100644 --- a/app/src/main/res/layout/simple_dialog.xml +++ b/app/src/main/res/layout/simple_dialog.xml @@ -59,6 +59,17 @@ + + + + diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml index e15c05094..617abeb39 100644 --- a/app/src/main/res/values-land/dimens.xml +++ b/app/src/main/res/values-land/dimens.xml @@ -16,7 +16,6 @@ - 72dp - 12dp + 12dp diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index 35a410999..dace243cf 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -16,9 +16,8 @@ - 72dp - 8dp - 32dp + 8dp + 32dp 48dp diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6aacb95d6..f28872064 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -77,6 +77,7 @@ 搜索 重试 跳页 + 未知 首页 热门 @@ -84,10 +85,13 @@ 收藏 下载 设置 + 注册 登录 退出 用户名 密码 + 显示 + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a9a02d7d2..c7788ad8d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -85,6 +85,10 @@ #20000000 + + #20000000 + #20ffffff + #8a000000 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index ecba24f6f..a354bacb3 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -15,14 +15,18 @@ --> + + 72dp + 24dp + 16dp + 32dp + 64dip + 56dp - 72dp - 24dp - 16dp - 32dp + 24dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78a94a68b..84ae04239 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -98,16 +98,21 @@ Retry Go to Unknown + Homepage What\'s hot History Favorite Download Settings + Sign up Sign in Sign out Username Password + Display + EH +