From 43837ef9c788029d6fcbecc03678abbfeb40c0c0 Mon Sep 17 00:00:00 2001 From: seven332 Date: Wed, 27 Jan 2016 00:54:39 +0800 Subject: [PATCH] Add GalleryDetailScene --- .../ehviewer/ui/scene/GalleryDetailScene.java | 209 ++++++++++++++++++ .../ehviewer/ui/scene/GalleryListScene.java | 66 +++++- .../ui/scene/TransitionNameFactory.java | 36 +++ .../java/com/hippo/scene/SceneFragment.java | 12 +- .../java/com/hippo/scene/StageActivity.java | 23 +- .../com/hippo/scene/TransitionHelper.java | 26 +++ .../main/java/com/hippo/utils/ApiHelper.java | 24 ++ .../main/res/layout/gallery_detail_header.xml | 71 ++++++ .../main/res/layout/scene_gallery_detail.xml | 60 +++++ app/src/main/res/transition/trans_move.xml | 21 ++ app/src/main/res/values/dimens.xml | 3 + 11 files changed, 546 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java create mode 100644 app/src/main/java/com/hippo/ehviewer/ui/scene/TransitionNameFactory.java create mode 100644 app/src/main/java/com/hippo/scene/TransitionHelper.java create mode 100644 app/src/main/java/com/hippo/utils/ApiHelper.java create mode 100644 app/src/main/res/layout/gallery_detail_header.xml create mode 100644 app/src/main/res/layout/scene_gallery_detail.xml create mode 100644 app/src/main/res/transition/trans_move.xml diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java new file mode 100644 index 000000000..ca095256a --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -0,0 +1,209 @@ +/* + * Copyright 2016 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 + * 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. + */ + +package com.hippo.ehviewer.ui.scene; + +import android.annotation.TargetApi; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.hippo.easyrecyclerview.SimpleHolder; +import com.hippo.ehviewer.EhApplication; +import com.hippo.ehviewer.EhCacheKeyFactory; +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.client.EhUtils; +import com.hippo.ehviewer.client.data.GalleryInfo; +import com.hippo.utils.ApiHelper; +import com.hippo.view.ViewTransition; +import com.hippo.widget.LoadImageView; + +// TODO Update drawer checked item +public class GalleryDetailScene extends BaseScene { + + public final static String KEY_ACTION = "action"; + public static final String ACTION_GALLERY_INFO = "action_gallery_info"; + public static final String ACTION_GID_TOKEN = "action_gid_token"; + + public static final String KEY_GALLERY_INFO = "gallery_info"; + public static final String KEY_GID = "gid"; + public static final String KEY_TOKEN = "token"; + + public static final int TYPE_HEADER = 0; + public static final int TYPE_BUTTON = 1; + public static final int TYPE_INFO = 2; + public static final int TYPE_ACTION = 3; + public static final int TYPE_TAG = 4; + public static final int TYPE_COMMENT = 5; + public static final int TYPE_PREVIEW = 6; + public static final int TYPE_PROGRESS = 7; + + private EhClient mClient; + + private RecyclerView mRecyclerView; + private View mMainProgressView; + private ViewGroup mFailedView; + private TextView mFailedText; + private ViewTransition mViewTransition; + + // Header + private View mHeader; + private LoadImageView mThumb; + private TextView mTitle; + private TextView mUploader; + private TextView mCategory; + + private String mAction; + private GalleryInfo mGalleryInfo; + private int mGid; + private String mKey; + + public GalleryDetailScene() { + + } + + private void handleArgs(Bundle args) { + if (args == null) { + return; + } + + String action = args.getString(KEY_ACTION); + mAction = action; + if (ACTION_GALLERY_INFO.equals(action)) { + mGalleryInfo = args.getParcelable(KEY_GALLERY_INFO); + } else if (ACTION_GID_TOKEN.equals(action)) { + mGid = args.getInt(KEY_GID); + mKey = args.getString(KEY_TOKEN); + } + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mClient = EhApplication.getEhClient(getContext()); + + handleArgs(getArguments()); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void bindView() { + int gid = -1; + boolean notFound = true; + if (ACTION_GALLERY_INFO.equals(mAction) && mGalleryInfo != null) { + GalleryInfo gi = mGalleryInfo; + gid = gi.gid; + mThumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true); + mTitle.setText(gi.title); + mUploader.setText(gi.uploader); + mCategory.setText(EhUtils.getCategory(gi.category)); + mCategory.setTextColor(EhUtils.getCategoryColor(gi.category)); + notFound = false; + } else if (ACTION_GID_TOKEN.equals(mAction)) { + gid = mGid; + // TODO + } + + if (ApiHelper.SUPPORT_TRANSITION && gid != -1) { + mThumb.setTransitionName(TransitionNameFactory.getThumbTransitionName(gid)); + mTitle.setTransitionName(TransitionNameFactory.getTitleTransitionName(gid)); + mUploader.setTransitionName(TransitionNameFactory.getUploaderTransitionName(gid)); + mCategory.setTransitionName(TransitionNameFactory.getCategoryTransitionName(gid)); + } + + if (notFound) { + // TODO Show not found error + } + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.scene_gallery_detail, container, false); + + ViewGroup main = (ViewGroup) view.findViewById(R.id.main); + mRecyclerView = (RecyclerView) main.findViewById(R.id.recycler_view); + mMainProgressView = main.findViewById(R.id.progress_view); + mFailedView = (ViewGroup) main.findViewById(R.id.tip); + mFailedText = (TextView) mFailedView.getChildAt(1); + mViewTransition = new ViewTransition(mRecyclerView, mMainProgressView, mFailedView); + + mRecyclerView.setAdapter(new GalleryDetailAdapter()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + + mHeader = inflater.inflate(R.layout.gallery_detail_header, mRecyclerView, false); + mThumb = (LoadImageView) mHeader.findViewById(R.id.thumb); + mTitle = (TextView) mHeader.findViewById(R.id.title); + mUploader = (TextView) mHeader.findViewById(R.id.uploader); + mCategory = (TextView) mHeader.findViewById(R.id.category); + + bindView(); + + return view; + } + + private class GalleryDetailAdapter extends RecyclerView.Adapter { + + @Override + public SimpleHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case TYPE_HEADER: + return new SimpleHolder(mHeader); + /* + case TYPE_BUTTON: + return new SimpleHolder(mButton); + case TYPE_INFO: + return new SimpleHolder(mInfo); + case TYPE_ACTION: + return new SimpleHolder(mAction); + case TYPE_TAG: + return new SimpleHolder(mTag); + case TYPE_COMMENT: + return new SimpleHolder(mComment); + case TYPE_PREVIEW: + return new SimpleHolder(mPreview); + case TYPE_PROGRESS: + return new SimpleHolder(mProgress); + */ + default: + throw new IllegalStateException("Unknown type " + viewType); + } + } + + @Override + public void onBindViewHolder(SimpleHolder holder, int position) { + + } + + @Override + public int getItemCount() { + return 1; + } + + @Override + public int getItemViewType(int position) { + return TYPE_HEADER; // TODO + } + } +} 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 7ea131aa8..00f5a6700 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 @@ -18,20 +18,26 @@ package com.hippo.ehviewer.ui.scene; import android.animation.Animator; import android.animation.ValueAnimator; +import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.ImageSpan; +import android.transition.TransitionInflater; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -60,6 +66,8 @@ import com.hippo.ehviewer.widget.SearchBarLayout; import com.hippo.ehviewer.widget.SearchLayout; import com.hippo.ehviewer.widget.SimpleRatingView; import com.hippo.rippleold.RippleSalon; +import com.hippo.scene.TransitionHelper; +import com.hippo.utils.ApiHelper; import com.hippo.vector.VectorDrawable; import com.hippo.view.ViewTransition; import com.hippo.widget.ContentLayout; @@ -70,6 +78,8 @@ import com.hippo.yorozuya.MathUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +// TODO store list data to temp file in onSaveInstanceState and save file path +// TODO new view fill recreate onResume, so remember to save, restore and free memory public final class GalleryListScene extends BaseScene implements EasyRecyclerView.OnItemClickListener, SearchBar.Helper, SearchBar.OnStateChangeListener, FastScroller.OnDragHandlerListener, @@ -160,6 +170,10 @@ public final class GalleryListScene extends BaseScene @Override public void onCreate(@Nullable Bundle savedInstanceState) { + + Log.d("TAG", "GalleryListScene onCreate"); + + super.onCreate(savedInstanceState); mClient = EhApplication.getEhClient(getContext()); @@ -227,6 +241,9 @@ public final class GalleryListScene extends BaseScene @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + Log.d("TAG", "GalleryListScene onCreateView"); + View view = inflater.inflate(R.layout.scene_gallery_list, container, false); Resources resources = getContext().getResources(); @@ -339,9 +356,46 @@ public final class GalleryListScene extends BaseScene } } + private static class GalleryDetailTransaction implements TransitionHelper { + + private GalleryListHolder mHolder; + + public GalleryDetailTransaction(GalleryListHolder holder) { + mHolder = holder; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public void onTransition(Context context, FragmentTransaction transaction, + Fragment exit, Fragment enter) { + exit.setSharedElementReturnTransition( + TransitionInflater.from(context).inflateTransition(R.transition.trans_move)); + exit.setExitTransition( + TransitionInflater.from(context).inflateTransition(android.R.transition.fade)); + enter.setSharedElementEnterTransition( + TransitionInflater.from(context).inflateTransition(R.transition.trans_move)); + enter.setEnterTransition( + TransitionInflater.from(context).inflateTransition(android.R.transition.fade)); + transaction.addSharedElement(mHolder.thumb, mHolder.thumb.getTransitionName()); + transaction.addSharedElement(mHolder.title, mHolder.title.getTransitionName()); + transaction.addSharedElement(mHolder.uploader, mHolder.uploader.getTransitionName()); + transaction.addSharedElement(mHolder.category, mHolder.category.getTransitionName()); + } + } + @Override public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) { - return false; + GalleryInfo gi = mHelper.getDataAt(position); + Bundle args = new Bundle(); + args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO); + args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, gi); + if (ApiHelper.SUPPORT_TRANSITION) { + GalleryListHolder holder = (GalleryListHolder) mRecyclerView.getChildViewHolder(view); + startScene(GalleryDetailScene.class, args, new GalleryDetailTransaction(holder)); + } else { + startScene(GalleryDetailScene.class, args); + } + return true; } private void showFab() { @@ -748,6 +802,7 @@ public final class GalleryListScene extends BaseScene } @Override + @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void onBindViewHolder(GalleryListHolder holder, int position) { GalleryInfo gi = mHelper.getDataAt(position); holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true); @@ -762,6 +817,15 @@ public final class GalleryListScene extends BaseScene } holder.posted.setText(gi.posted); holder.simpleLanguage.setText(gi.simpleLanguage); + + // Update transition name + if (ApiHelper.SUPPORT_TRANSITION) { + int gid = gi.gid; + holder.thumb.setTransitionName(TransitionNameFactory.getThumbTransitionName(gid)); + holder.title.setTransitionName(TransitionNameFactory.getTitleTransitionName(gid)); + holder.uploader.setTransitionName(TransitionNameFactory.getUploaderTransitionName(gid)); + holder.category.setTransitionName(TransitionNameFactory.getCategoryTransitionName(gid)); + } } @Override diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/TransitionNameFactory.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/TransitionNameFactory.java new file mode 100644 index 000000000..6ea8731bb --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/TransitionNameFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 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 + * 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. + */ + +package com.hippo.ehviewer.ui.scene; + +public final class TransitionNameFactory { + + public static String getThumbTransitionName(int gid) { + return "thumb:" + gid; + } + + public static String getTitleTransitionName(int gid) { + return "title:" + gid; + } + + public static String getUploaderTransitionName(int gid) { + return "uploader:" + gid; + } + + public static String getCategoryTransitionName(int gid) { + return "category:" + gid; + } +} diff --git a/app/src/main/java/com/hippo/scene/SceneFragment.java b/app/src/main/java/com/hippo/scene/SceneFragment.java index ff2ff1eb7..607bfb61f 100644 --- a/app/src/main/java/com/hippo/scene/SceneFragment.java +++ b/app/src/main/java/com/hippo/scene/SceneFragment.java @@ -47,13 +47,21 @@ public class SceneFragment extends Fragment { public void onNewArguments(@NonNull Bundle args) {} public void startScene(Class clazz) { - startScene(clazz, null); + startScene(clazz, null, null); } public void startScene(Class clazz, Bundle args) { + startScene(clazz, args, null); + } + + public void startScene(Class clazz, TransitionHelper transitionHelper) { + startScene(clazz, null, transitionHelper); + } + + public void startScene(Class clazz, Bundle args, TransitionHelper transitionHelper) { FragmentActivity activity = getActivity(); if (activity instanceof StageActivity) { - ((StageActivity) activity).startScene(clazz, args); + ((StageActivity) activity).startScene(clazz, args, transitionHelper); } } diff --git a/app/src/main/java/com/hippo/scene/StageActivity.java b/app/src/main/java/com/hippo/scene/StageActivity.java index f87f68b7c..0dd7316da 100644 --- a/app/src/main/java/com/hippo/scene/StageActivity.java +++ b/app/src/main/java/com/hippo/scene/StageActivity.java @@ -61,10 +61,19 @@ public abstract class StageActivity extends AppCompatActivity { } public void startScene(Class clazz) { - startScene(clazz, null); + startScene(clazz, null, null); } public void startScene(Class clazz, Bundle args) { + startScene(clazz, args, null); + } + + public void startScene(Class clazz, TransitionHelper transitionHelper) { + startScene(clazz, null, transitionHelper); + } + + public void startScene(Class clazz, + Bundle args, TransitionHelper transitionHelper) { FragmentManager fragmentManager = getSupportFragmentManager(); // Old scene @@ -94,7 +103,12 @@ public abstract class StageActivity extends AppCompatActivity { mSceneTagList.add(newTag); FragmentTransaction transaction = fragmentManager.beginTransaction(); - transaction.setCustomAnimations(R.anim.fragment_translate_in, R.anim.fragment_translate_out); + if (transitionHelper != null && old != null) { + transitionHelper.onTransition(this, transaction, old, scene); + } else { + transaction.setCustomAnimations(R.anim.fragment_translate_in, R.anim.fragment_translate_out); + } + transaction.remove(scene); if (old != null) { transaction.detach(old); } @@ -158,6 +172,11 @@ public abstract class StageActivity extends AppCompatActivity { // Remove tag mSceneTagList.remove(index); + + // Update SoftInputMode + if (next instanceof SceneFragment) { + getWindow().setSoftInputMode(((SceneFragment) scene).getSoftInputMode()); + } } @Override diff --git a/app/src/main/java/com/hippo/scene/TransitionHelper.java b/app/src/main/java/com/hippo/scene/TransitionHelper.java new file mode 100644 index 000000000..d8245f112 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/TransitionHelper.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016 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 + * 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. + */ + +package com.hippo.scene; + +import android.content.Context; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; + +public interface TransitionHelper { + + void onTransition(Context context, FragmentTransaction transaction, Fragment exit, Fragment enter); +} diff --git a/app/src/main/java/com/hippo/utils/ApiHelper.java b/app/src/main/java/com/hippo/utils/ApiHelper.java new file mode 100644 index 000000000..990e86d2d --- /dev/null +++ b/app/src/main/java/com/hippo/utils/ApiHelper.java @@ -0,0 +1,24 @@ +/* + * Copyright 2016 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 + * 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. + */ + +package com.hippo.utils; + +import android.os.Build; + +public final class ApiHelper { + + public static final boolean SUPPORT_TRANSITION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; +} diff --git a/app/src/main/res/layout/gallery_detail_header.xml b/app/src/main/res/layout/gallery_detail_header.xml new file mode 100644 index 000000000..63ab6f5e1 --- /dev/null +++ b/app/src/main/res/layout/gallery_detail_header.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/scene_gallery_detail.xml b/app/src/main/res/layout/scene_gallery_detail.xml new file mode 100644 index 000000000..5f0e99c94 --- /dev/null +++ b/app/src/main/res/layout/scene_gallery_detail.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/transition/trans_move.xml b/app/src/main/res/transition/trans_move.xml new file mode 100644 index 000000000..cd02a2ffd --- /dev/null +++ b/app/src/main/res/transition/trans_move.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 4ff0f19fc..bcdd03efd 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -70,4 +70,7 @@ 16dp + 128dp + 192dp +