Improve scene animation
This commit is contained in:
1 parent
7e252eb096
commit
cac0aedc42
11 files changed
+208
-112
No files matched your search
@@ -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<GalleryDetail> {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user