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 index e6764efcd..9990ec57f 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -22,8 +22,11 @@ import android.content.res.Resources; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; import android.support.v7.widget.PopupMenu; import android.text.TextUtils; +import android.transition.TransitionInflater; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; @@ -31,7 +34,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RatingBar; -import android.widget.ScrollView; import android.widget.TextView; import com.hippo.ehviewer.EhApplication; @@ -51,6 +53,7 @@ import com.hippo.ehviewer.client.data.ListUrlBuilder; import com.hippo.rippleold.RippleSalon; import com.hippo.scene.SceneFragment; import com.hippo.scene.StageActivity; +import com.hippo.scene.TransitionHelper; import com.hippo.text.Html; import com.hippo.text.URLImageGetter; import com.hippo.util.ApiHelper; @@ -58,6 +61,7 @@ import com.hippo.util.ExceptionUtils; import com.hippo.util.ReadableTime; import com.hippo.vector.AnimatedVectorDrawable; import com.hippo.vector.VectorDrawable; +import com.hippo.view.ViewTransition; import com.hippo.widget.AutoWrapLayout; import com.hippo.widget.LoadImageView; import com.hippo.widget.SimpleGridLayout; @@ -80,10 +84,9 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene private static final String KEY_GALLERY_DETAIL = "gallery_detail"; private static final String KEY_REQUEST_ID = "request_id"; - private ScrollView mMainView; - private View mProgressView; private ViewGroup mFailedView; private TextView mFailedText; + private ViewTransition mViewTransition; // Header private View mHeader; @@ -127,6 +130,8 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene // Progress private View mProgress; + private ViewTransition mViewTransition2; + private AnimatedVectorDrawable mHeartDrawable; private AnimatedVectorDrawable mHeartOutlineDrawable; private PopupMenu mPopupMenu; @@ -258,13 +263,13 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene View view = inflater.inflate(R.layout.scene_gallery_detail, container, false); ViewGroup main = (ViewGroup) view.findViewById(R.id.main); - mMainView = (ScrollView) main.findViewById(R.id.scroll_view); - mProgressView = main.findViewById(R.id.progress_view); + View mainView = main.findViewById(R.id.scroll_view); + View progressView = main.findViewById(R.id.progress_view); mFailedView = (ViewGroup) main.findViewById(R.id.tip); mFailedText = (TextView) mFailedView.getChildAt(1); mFailedView.setOnClickListener(this); + mViewTransition = new ViewTransition(mainView, progressView, mFailedView); - View mainView = mMainView; mHeader = mainView.findViewById(R.id.header); mThumb = (LoadImageView) mHeader.findViewById(R.id.thumb); mTitle = (TextView) mHeader.findViewById(R.id.title); @@ -326,6 +331,8 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene mProgress = mainView.findViewById(R.id.progress); + mViewTransition2 = new ViewTransition(mBelowHeader, mProgress); + if (prepareData()) { if (mGalleryDetail != null) { bindViewSecond(); @@ -337,7 +344,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene } else { mFailedText.setText(R.string.cannot_find_gallery); } - adjustViewVisibility(); + adjustViewVisibility(false); return view; } @@ -346,10 +353,9 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene public void onDestroyView() { super.onDestroyView(); - mMainView = null; - mProgressView = null; mFailedView = null; mFailedText = null; + mViewTransition = null; mHeader = null; mThumb = null; @@ -391,6 +397,8 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene mProgress = null; + mViewTransition2 = null; + mHeartDrawable = null; mHeartOutlineDrawable = null; mPopupMenu = null; @@ -440,30 +448,23 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene return true; } - private void adjustViewVisibility() { + private void adjustViewVisibility(boolean animation) { if (mGalleryDetail != null) { - mMainView.setVisibility(View.VISIBLE); - mProgressView.setVisibility(View.GONE); - mFailedView.setVisibility(View.GONE); - - mBelowHeader.setVisibility(View.VISIBLE); - mProgress.setVisibility(View.GONE); + // Show mMainView + mViewTransition.showView(0, animation); + // Show mBelowHeader + mViewTransition2.showView(0, animation); } else if (mGalleryInfo != null) { - mMainView.setVisibility(View.VISIBLE); - mProgressView.setVisibility(View.GONE); - mFailedView.setVisibility(View.GONE); - - mBelowHeader.setVisibility(View.GONE); - mProgress.setVisibility(View.VISIBLE); + // Show mMainView + mViewTransition.showView(0, animation); + // Show mProgress + mViewTransition2.showView(1, animation); + } else if (TextUtils.isEmpty(mFailedText.getText())) { + // Show mProgressView + mViewTransition.showView(1, animation); } else { - mMainView.setVisibility(View.GONE); - if (TextUtils.isEmpty(mFailedText.getText())) { - mProgressView.setVisibility(View.VISIBLE); - mFailedView.setVisibility(View.GONE); - } else { - mProgressView.setVisibility(View.GONE); - mFailedView.setVisibility(View.VISIBLE); - } + // Show mFailedView + mViewTransition.showView(2, animation); } } @@ -729,7 +730,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene if (mFailedView == v) { if (request()) { mFailedText.setText(""); - adjustViewVisibility(); + adjustViewVisibility(true); } } else if (mOtherActions == v) { ensurePopMenu(); @@ -772,16 +773,69 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene } } + @Override + public void onBackPressed() { + if (mViewTransition.getShownViewIndex() == 0 && ApiHelper.SUPPORT_TRANSITION) { + int[] location = new int[2]; + mThumb.getLocationInWindow(location); + // Only show transaction when thumb can be seen + if (location[1] + mThumb.getHeight() > 0) { + finish(new EnterGalleryListTransaction(mThumb, mTitle, mUploader, mCategory)); + return; + } + } + + finish(); + } + + private static class EnterGalleryListTransaction implements TransitionHelper { + + private View mThumb; + private View mTitle; + private View mUploader; + private View mCategory; + + public EnterGalleryListTransaction(View thumb, View title, View uploader, View category) { + mThumb = thumb; + mTitle = title; + mUploader = uploader; + mCategory = category; + } + + @Override + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public boolean onTransition(Context context, + FragmentTransaction transaction, Fragment exit, Fragment enter) { + if (!(enter instanceof GalleryListScene)) { + return false; + } + + 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(mThumb, mThumb.getTransitionName()); + transaction.addSharedElement(mTitle, mTitle.getTransitionName()); + transaction.addSharedElement(mUploader, mUploader.getTransitionName()); + transaction.addSharedElement(mCategory, mCategory.getTransitionName()); + return true; + } + } + private void onGetGalleryDetailSuccess(GalleryDetail result) { mGalleryDetail = result; - adjustViewVisibility(); + adjustViewVisibility(true); bindViewSecond(); } private void onGetGalleryDetailFailure(Exception e) { String error = ExceptionUtils.getReadableString(getContext(), e); mFailedText.setText(error); - adjustViewVisibility(); + adjustViewVisibility(true); } private static class GetGalleryDetailListener implements EhClient.Callback { 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 9f2a78bb9..10ace1052 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 @@ -372,35 +372,48 @@ public final class GalleryListScene extends BaseScene } @Override - public boolean onBackPressed() { + public void onBackPressed() { + boolean handle; switch (mState) { default: case STATE_NORMAL: - return checkDoubleClickExit(); + handle = checkDoubleClickExit(); + break; case STATE_SIMPLE_SEARCH: setState(STATE_NORMAL); - return true; + handle = true; + break; case STATE_SEARCH: setState(STATE_NORMAL); - return true; + handle = true; + break; case STATE_SEARCH_SHOW_LIST: setState(STATE_SEARCH); - return true; + handle = true; + break; + } + + if (!handle) { + finish(); } } - private static class GalleryDetailTransaction implements TransitionHelper { + private static class EnterGalleryDetailTransaction implements TransitionHelper { private GalleryListHolder mHolder; - public GalleryDetailTransaction(GalleryListHolder holder) { + public EnterGalleryDetailTransaction(GalleryListHolder holder) { mHolder = holder; } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override - public void onTransition(Context context, FragmentTransaction transaction, + public boolean onTransition(Context context, FragmentTransaction transaction, Fragment exit, Fragment enter) { + if (!(enter instanceof GalleryDetailScene)) { + return false; + } + exit.setSharedElementReturnTransition( TransitionInflater.from(context).inflateTransition(R.transition.trans_move)); exit.setExitTransition( @@ -413,6 +426,7 @@ public final class GalleryListScene extends BaseScene transaction.addSharedElement(mHolder.title, mHolder.title.getTransitionName()); transaction.addSharedElement(mHolder.uploader, mHolder.uploader.getTransitionName()); transaction.addSharedElement(mHolder.category, mHolder.category.getTransitionName()); + return true; } } @@ -424,7 +438,7 @@ public final class GalleryListScene extends BaseScene args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, gi); if (ApiHelper.SUPPORT_TRANSITION) { GalleryListHolder holder = (GalleryListHolder) mRecyclerView.getChildViewHolder(view); - startScene(GalleryDetailScene.class, args, new GalleryDetailTransaction(holder)); + startScene(GalleryDetailScene.class, args, new EnterGalleryDetailTransaction(holder)); } else { startScene(GalleryDetailScene.class, args); } diff --git a/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.java b/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.java index 13676469b..5e4dde7a2 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.java @@ -38,9 +38,7 @@ import android.widget.RadioGroup; import android.widget.TextView; import com.hippo.easyrecyclerview.EasyRecyclerView; -import com.hippo.easyrecyclerview.MarginItemDecoration; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.client.EhUtils; import com.hippo.ehviewer.client.data.ListUrlBuilder; import com.hippo.rippleold.RippleSalon; @@ -125,8 +123,6 @@ public class SearchLayout extends EasyRecyclerView implements CompoundButton.OnC setHasFixedSize(true); setClipToPadding(false); //setItemAnimator(mAnimator); - addItemDecoration(new MarginItemDecoration( - getContext().getResources().getDimensionPixelOffset(R.dimen.list_item_margin))); int paddingH = resources.getDimensionPixelOffset(R.dimen.list_content_margin_h); int paddingV = resources.getDimensionPixelOffset(R.dimen.list_content_margin_v); setPadding(paddingV, paddingH, paddingV, paddingH); diff --git a/app/src/main/java/com/hippo/scene/SceneFragment.java b/app/src/main/java/com/hippo/scene/SceneFragment.java index f2e757d3b..474b426ca 100644 --- a/app/src/main/java/com/hippo/scene/SceneFragment.java +++ b/app/src/main/java/com/hippo/scene/SceneFragment.java @@ -70,9 +70,13 @@ public class SceneFragment extends Fragment { } public void finish() { + finish(null); + } + + public void finish(TransitionHelper transitionHelper) { FragmentActivity activity = getActivity(); if (activity instanceof StageActivity) { - ((StageActivity) activity).finishScene(this); + ((StageActivity) activity).finishScene(this, transitionHelper); } } @@ -95,11 +99,8 @@ public class SceneFragment extends Fragment { } } - /** - * @return true for handle this back pressed action - */ - public boolean onBackPressed() { - return false; + public void onBackPressed() { + finish(); } @Override diff --git a/app/src/main/java/com/hippo/scene/StageActivity.java b/app/src/main/java/com/hippo/scene/StageActivity.java index 6e6f984b2..f049a803f 100644 --- a/app/src/main/java/com/hippo/scene/StageActivity.java +++ b/app/src/main/java/com/hippo/scene/StageActivity.java @@ -165,9 +165,18 @@ public abstract class StageActivity extends AppCompatActivity { FragmentTransaction transaction = fragmentManager.beginTransaction(); if (currentFragment != null) { - if (transitionHelper != null) { - transitionHelper.onTransition(this, transaction, currentFragment, newScene); - } else { + if (transitionHelper == null || !transitionHelper.onTransition( + this, transaction, currentFragment, newScene)) { + // Clear shared item + currentFragment.setSharedElementEnterTransition(null); + currentFragment.setSharedElementReturnTransition(null); + currentFragment.setEnterTransition(null); + currentFragment.setExitTransition(null); + newScene.setSharedElementEnterTransition(null); + newScene.setSharedElementReturnTransition(null); + newScene.setEnterTransition(null); + newScene.setExitTransition(null); + // Set default animation transaction.setCustomAnimations(R.anim.scene_open_enter, R.anim.scene_open_exit); } transaction.detach(currentFragment); @@ -198,10 +207,14 @@ public abstract class StageActivity extends AppCompatActivity { } public void finishScene(SceneFragment scene) { - finishScene(scene.getTag()); + finishScene(scene, null); } - private void finishScene(String tag) { + public void finishScene(SceneFragment scene, TransitionHelper transitionHelper) { + finishScene(scene.getTag(), transitionHelper); + } + + private void finishScene(String tag, TransitionHelper transitionHelper) { FragmentManager fragmentManager = getSupportFragmentManager(); // Get scene @@ -232,15 +245,25 @@ public abstract class StageActivity extends AppCompatActivity { } FragmentTransaction transaction = fragmentManager.beginTransaction(); - transaction.setCustomAnimations(R.anim.scene_close_enter, R.anim.scene_close_exit); - transaction.remove(scene); if (next != null) { - if (next.isDetached()) { - transaction.attach(next); - } else { - Log.e(TAG, "finishScene: The scene should be detached"); + if (transitionHelper == null || !transitionHelper.onTransition( + this, transaction, scene, next)) { + // Clear shared item + scene.setSharedElementEnterTransition(null); + scene.setSharedElementReturnTransition(null); + scene.setEnterTransition(null); + scene.setExitTransition(null); + next.setSharedElementEnterTransition(null); + next.setSharedElementReturnTransition(null); + next.setEnterTransition(null); + next.setExitTransition(null); + // Do not show animate if it is not the first fragment + transaction.setCustomAnimations(R.anim.scene_close_enter, R.anim.scene_close_exit); } + // Attach fragment + transaction.attach(next); } + transaction.remove(scene); transaction.commit(); // Remove tag @@ -268,13 +291,7 @@ public abstract class StageActivity extends AppCompatActivity { } scene = (SceneFragment) fragment; - if (!scene.onBackPressed()) { - if (size > 0) { - finishScene(tag); - } else { - finish(); - } - } + scene.onBackPressed(); } public SceneFragment findSceneByTag(String tag) { diff --git a/app/src/main/java/com/hippo/scene/StageLayout.java b/app/src/main/java/com/hippo/scene/StageLayout.java index ef3543c44..3befd8469 100644 --- a/app/src/main/java/com/hippo/scene/StageLayout.java +++ b/app/src/main/java/com/hippo/scene/StageLayout.java @@ -104,7 +104,7 @@ public class StageLayout extends FrameLayout { } View view1 = mSuperDisappearingChildren.get(0); - View view2 = getChildAt(1); // dump view + View view2 = getChildAt(1); // Skip dump view String tag1 = getViewTag(view1); String tag2 = getViewTag(view2); try { diff --git a/app/src/main/java/com/hippo/scene/TransitionHelper.java b/app/src/main/java/com/hippo/scene/TransitionHelper.java index d8245f112..961cb264a 100644 --- a/app/src/main/java/com/hippo/scene/TransitionHelper.java +++ b/app/src/main/java/com/hippo/scene/TransitionHelper.java @@ -22,5 +22,5 @@ import android.support.v4.app.FragmentTransaction; public interface TransitionHelper { - void onTransition(Context context, FragmentTransaction transaction, Fragment exit, Fragment enter); + boolean onTransition(Context context, FragmentTransaction transaction, Fragment exit, Fragment enter); } diff --git a/app/src/main/res/layout/gallery_detail_actions.xml b/app/src/main/res/layout/gallery_detail_actions.xml index c9e3e8f00..a0c5e9b1c 100644 --- a/app/src/main/res/layout/gallery_detail_actions.xml +++ b/app/src/main/res/layout/gallery_detail_actions.xml @@ -47,7 +47,8 @@ android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="@string/favorite" - android:drawablePadding="8dp"/> + android:drawablePadding="8dp" + android:textColor="@color/primary_text_light"/> + android:drawablePadding="8dp" + android:textColor="@color/primary_text_light"/> @@ -66,7 +68,8 @@ android:layout_marginLeft="16dp" android:gravity="center_horizontal" android:drawablePadding="8dp" - android:drawableTop="@drawable/ic_utorrent_primary_x48"/> + android:drawableTop="@drawable/ic_utorrent_primary_x48" + android:textColor="@color/primary_text_light"/> + android:drawableTop="@drawable/ic_share_primary_x48" + android:textColor="@color/primary_text_light"/> + android:drawableTop="@drawable/ic_thumb_up_primary_x48" + android:textColor="@color/primary_text_light"/> @@ -103,6 +108,7 @@ android:id="@+id/rating_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center_horizontal"/> + android:layout_gravity="center_horizontal" + android:textColor="@color/primary_text_light"/> diff --git a/app/src/main/res/layout/gallery_detail_content.xml b/app/src/main/res/layout/gallery_detail_content.xml index 97059ab10..67f7b6d0f 100644 --- a/app/src/main/res/layout/gallery_detail_content.xml +++ b/app/src/main/res/layout/gallery_detail_content.xml @@ -19,39 +19,43 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:animateLayoutChanges="true"> + android:orientation="vertical"> - + android:layout_height="wrap_content"> + + + + + + + + + + + + + + - - - - - - - - - - - - + layout="@layout/gallery_detail_progress"/> + diff --git a/app/src/main/res/layout/gallery_detail_info.xml b/app/src/main/res/layout/gallery_detail_info.xml index 6a63867ed..dfd77841e 100644 --- a/app/src/main/res/layout/gallery_detail_info.xml +++ b/app/src/main/res/layout/gallery_detail_info.xml @@ -36,14 +36,16 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" - android:singleLine="true"/> + android:singleLine="true" + android:textColor="@color/primary_text_light"/> + android:singleLine="true" + android:textColor="@color/primary_text_light"/> + android:singleLine="true" + android:textColor="@color/primary_text_light"/> @@ -64,7 +67,8 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" - android:singleLine="true"/> + android:singleLine="true" + android:textColor="@color/primary_text_light"/> + android:singleLine="true" + android:textColor="@color/primary_text_light"/> diff --git a/app/src/main/res/layout/scene_gallery_detail.xml b/app/src/main/res/layout/scene_gallery_detail.xml index cb0ab9c02..8519d8e6e 100644 --- a/app/src/main/res/layout/scene_gallery_detail.xml +++ b/app/src/main/res/layout/scene_gallery_detail.xml @@ -19,8 +19,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main" android:layout_width="match_parent" - android:layout_height="match_parent" - android:animateLayoutChanges="true"> + android:layout_height="match_parent">