Add Preference

This commit is contained in:
seven332 committed 2015-05-28 21:29:20 +08:00
1 parent c1af94afa0
commit aa61dada92
44 files changed
+1447 -77

No files matched your search

@@ -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;
}
@@ -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
};
}
}
@@ -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) {
@@ -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();
}
}
@@ -37,6 +37,9 @@ public abstract class Curtain {
return scene != null && scene.getId() == mPreviousSceneId;
}
protected void onReplace() {
}
/**
* Called when
*
+5 -2
View File
@@ -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<Parcelable> 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<Parcelable> savedStates
= savedInstanceState.getSparseParcelableArray(getStateKey());
@@ -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);
}
}
@@ -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);
}
}
@@ -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<CharSequence>(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();
}
}
@@ -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);
@@ -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")
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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<Method> 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);
}
}
}
@@ -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
}
}
@@ -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;
}
}
@@ -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<PreferenceHeader> 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();
}
}
}
@@ -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);
}
}
@@ -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<PreferenceSet> mPreferenceSetList = new ArrayList<>();
private List<PreferenceBase> 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<PreferenceSet> preferenceSetList = mPreferenceSetList;
preferenceSetList.clear();
Collections.addAll(preferenceSetList, preferenceSets);
// Update mPreferenceBasesList
List<PreferenceBase> 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<RecyclerView.ViewHolder> {
@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);
}
}
}
@@ -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<Preference> 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();
}
}
@@ -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;
}
}
+7 -13
View File
@@ -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);
}
/**
@@ -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);
}
}
@@ -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));
}
@@ -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;
}
}
@@ -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
@@ -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);
}
}
+68
View File
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. -->
<com.hippo.widget.SolidLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/preference_minimum_height"
android:paddingLeft="@dimen/keyline_margin"
android:paddingRight="@dimen/keyline_margin"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textSize="@dimen/text_little_small"
android:textColor="@color/primary_text_light"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView
android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="@color/secondary_text_light"
android:maxLines="4"
tools:ignore="RtlHardcoded"/>
</LinearLayout>
<!-- Preference should place its actual preference widget here. -->
<FrameLayout
android:id="@+id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</com.hippo.widget.SolidLinearLayout>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_small"
android:textColor="@color/theme_accent"
android:paddingLeft="@dimen/keyline_margin"
android:paddingRight="@dimen/keyline_margin"
android:paddingTop="16dip" />
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_light"/>
@@ -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">
<ImageView
android:id="@+id/icon"
android:layout_width="@dimen/settings_header_image_size"
android:layout_height="@dimen/settings_header_image_size"
android:layout_width="@dimen/preference_header_image_size"
android:layout_height="@dimen/preference_header_image_size"
android:scaleType="centerInside"
android:layout_marginLeft="@dimen/settings_header_image_margin_start"
android:layout_marginRight="@dimen/settings_header_image_margin_end"
tools:ignore="RtlHardcoded"/>
android:layout_marginLeft="@dimen/preference_header_image_margin_start"
android:layout_marginRight="@dimen/preference_header_image_margin_end"
tools:ignore="RtlHardcoded"
android:contentDescription="@null"/>
<LinearLayout
android:layout_width="match_parent"
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
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
distributed under the License is distributed on an "AS IS" BASIS,
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.
-->
<!--
This layout file is used by the AlertDialog when displaying a list of items.
This layout file is inflated and used as the TextView to display individual
items.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:ellipsize="marquee"/>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
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
distributed under the License is distributed on an "AS IS" BASIS,
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.
-->
<CheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:gravity="center_vertical"
android:paddingLeft="12dip"
android:paddingRight="7dip"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:ellipsize="marquee"
tools:ignore="RtlHardcoded"/>
+11
View File
@@ -59,6 +59,17 @@
</com.hippo.widget.IndicatingScrollView>
<com.hippo.widget.IndicatingListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:paddingLeft="@dimen/simple_dialog_body_padding_left"
android:paddingRight="@dimen/simple_dialog_body_padding_right"
android:scrollbars="none"
tools:ignore="RtlHardcoded"/>
<FrameLayout
android:id="@+id/custom"
android:layout_width="match_parent"
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
+1 -2
View File
@@ -16,7 +16,6 @@
<resources>
<!-- Settings Header -->
<dimen name="settings_header_minimum_height">72dp</dimen>
<dimen name="settings_header_image_margin_start">12dp</dimen>
<dimen name="preference_header_image_margin_start">12dp</dimen>
</resources>
+2 -3
View File
@@ -16,9 +16,8 @@
<resources>
<!-- Settings Header -->
<dimen name="settings_header_minimum_height">72dp</dimen>
<dimen name="settings_header_image_margin_start">8dp</dimen>
<dimen name="settings_header_image_margin_end">32dp</dimen>
<dimen name="preference_header_image_margin_start">8dp</dimen>
<dimen name="preference_header_image_margin_end">32dp</dimen>
<!-- Snackbar -->
<dimen name="snackbar_interval">48dp</dimen>
@@ -77,6 +77,7 @@
<string name="search">搜索</string>
<string name="retry">重试</string>
<string name="_goto">跳页</string>
<string name="unknown">未知</string>
<string name="homepage">首页</string>
<string name="whatshot">热门</string>
@@ -84,10 +85,13 @@
<string name="favorite">收藏</string>
<string name="download">下载</string>
<string name="settings">设置</string>
<string name="signup">注册</string>
<string name="signin">登录</string>
<string name="signout">退出</string>
<string name="username">用户名</string>
<string name="password">密码</string>
<string name="display">显示</string>
</resources>
+4
View File
@@ -85,6 +85,10 @@
<!-- Scroll View -->
<color name="scroll_view_indicator">#20000000</color>
<!-- divider -->
<color name="divider_light">#20000000</color>
<color name="divider_dark">#20ffffff</color>
<!-- CheckTextView -->
<color name="check_text_view_mask">#8a000000</color>
+8 -4
View File
@@ -15,14 +15,18 @@
-->
<resources>
<!-- preference -->
<dimen name="preference_header_minimum_height">72dp</dimen>
<dimen name="preference_header_image_size">24dp</dimen>
<dimen name="preference_header_image_margin_start">16dp</dimen>
<dimen name="preference_header_image_margin_end">32dp</dimen>
<dimen name="preference_minimum_height">64dip</dimen>
<!-- Appbar -->
<dimen name="appbar_height">56dp</dimen>
<!-- Settings Header -->
<dimen name="settings_header_minimum_height">72dp</dimen>
<dimen name="settings_header_image_size">24dp</dimen>
<dimen name="settings_header_image_margin_start">16dp</dimen>
<dimen name="settings_header_image_margin_end">32dp</dimen>
<!-- DrawerList -->
<dimen name="drawer_list_drawable_size">24dp</dimen>
+5
View File
@@ -98,16 +98,21 @@
<string name="retry">Retry</string>
<string name="_goto">Go to</string>
<string name="unknown">Unknown</string>
<string name="homepage">Homepage</string>
<string name="whatshot">What\'s hot</string>
<string name="history">History</string>
<string name="favorite">Favorite</string>
<string name="download">Download</string>
<string name="settings">Settings</string>
<string name="signup">Sign up</string>
<string name="signin">Sign in</string>
<string name="signout">Sign out</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="display">Display</string>
<string name="eh" translatable="false">EH</string>
</resources>