Improve scene lifecycle

This commit is contained in:
seven332 committed 2015-07-02 16:57:52 +08:00
1 parent 3f6d3ea21c
commit f71883a2b9
15 files changed
+307 -210

No files matched your search

@@ -17,7 +17,6 @@
package com.hippo.ehviewer.ui.scene;
import android.content.res.Resources;
import android.os.Bundle;
import com.hippo.ehviewer.BuildConfig;
import com.hippo.ehviewer.Constants;
@@ -35,8 +34,8 @@ public class AdvanceSettingsScene extends PreferenceScene implements Preference.
private static final boolean DEFAULT_SHOW_APPLICATION_STATS = BuildConfig.DEBUG;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setTitle(R.string.settings);
setIcon(R.drawable.ic_arrow_left_dark);
@@ -2,8 +2,6 @@ package com.hippo.ehviewer.ui.scene;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
@@ -39,18 +37,9 @@ public class CommentScene extends AppbarScene {
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreateView();
if (savedInstanceState == null) {
onBindView();
} else {
onRestoreView(savedInstanceState);
}
}
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
private void onCreateView() {
Context context = getStageActivity();
Resources resources = context.getResources();
@@ -73,12 +62,18 @@ public class CommentScene extends AppbarScene {
mRecyclerView.setClipToPadding(false);
}
private void onBindView() {
@Override
protected void onBind() {
super.onBind();
handleAnnouncer(getAnnouncer());
}
private void onRestoreView(@Nullable Bundle savedInstanceState) {
// Empty
@Override
protected void onRestore() {
super.onRestore();
// mCommentList is already setted, nothing to do
}
@Override
@@ -17,7 +17,6 @@
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.Preference;
@@ -28,8 +27,8 @@ import com.hippo.scene.preference.PreferenceSet;
public class DisplaySettingsScene extends PreferenceScene {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setTitle(R.string.settings);
setIcon(R.drawable.ic_arrow_left_dark);
@@ -17,7 +17,6 @@
package com.hippo.ehviewer.ui.scene;
import android.content.res.Resources;
import android.os.Bundle;
import com.hippo.ehviewer.BuildConfig;
import com.hippo.ehviewer.Constants;
@@ -37,8 +36,8 @@ public final class EHSettingsScene extends PreferenceScene {
EhClient.SOURCE_EX : EhClient.SOURCE_G;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setTitle(R.string.settings);
setIcon(R.drawable.ic_arrow_left_dark);
@@ -20,8 +20,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.Html;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -174,8 +172,8 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setContentView(R.layout.scene_gallery_detail);
mDetailFrameLayout = (FrameLayout) findViewById(R.id.detail_frame_layout);
@@ -23,9 +23,7 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.text.TextUtils;
@@ -56,10 +54,10 @@ import com.hippo.ehviewer.util.EhUtils;
import com.hippo.ehviewer.widget.ContentLayout;
import com.hippo.ehviewer.widget.LoadImageView;
import com.hippo.ehviewer.widget.OffsetLayout;
import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.ehviewer.widget.SearchBar;
import com.hippo.ehviewer.widget.SearchDatabase;
import com.hippo.ehviewer.widget.SearchLayout;
import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.scene.Announcer;
import com.hippo.scene.Curtain;
import com.hippo.scene.Scene;
@@ -236,16 +234,16 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
}
@Override
protected void onRebirth(@Nullable Bundle savedInstanceState) {
super.onRebirth(savedInstanceState);
protected void onRebirth() {
super.onRebirth();
mGalleryListHelper = new GalleryListHelper(getStageActivity(), mGalleryListHelper);
}
@SuppressWarnings("deprecation")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setContentView(R.layout.scene_gallery_list);
mActivity = (ContentActivity) getStageActivity();
@@ -310,14 +308,14 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
mCornerFab.setDrawable(mAddDeleteDrawable);
// When scene start
if (savedInstanceState == null) {
if (!rebirth) {
handleAnnouncer(getAnnouncer());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
protected void onDie() {
super.onDie();
// Avoid memory leak
if (mGalleryListHelper.mListener != null) {
@@ -332,20 +330,6 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
((ContentActivity) getStageActivity()).setDrawerListActivatedPosition(mDrawerListActivatedPosition);
}
@Override
protected void saveInstanceState(Bundle outState) {
super.saveInstanceState(outState);
outState.putInt(KEY_STATE, mState);
}
@Override
protected void restoreInstanceState(@NonNull Bundle savedInstanceState) {
super.restoreInstanceState(savedInstanceState);
setState(savedInstanceState.getInt(KEY_STATE), false);
}
@Override
protected void onGetFitPaddingBottom(int b) {
// Content Layout
@@ -17,7 +17,6 @@
package com.hippo.ehviewer.ui.scene;
import android.content.res.Resources;
import android.os.Bundle;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.ContentActivity;
@@ -27,17 +26,19 @@ import com.hippo.scene.preference.PreferenceHeaderScene;
public final class MainSettingsScene extends PreferenceHeaderScene {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
((ContentActivity) getStageActivity()).setDrawerListActivatedPosition(ContentActivity.DRAWER_LIST_SETTINGS);
setTitle(R.string.settings);
setIcon(R.drawable.ic_arrow_left_dark);
Resources resources = getStageActivity().getResources();
setPreferenceHeaders(getPreferenceHeaders());
}
PreferenceHeader[] phs = new PreferenceHeader[] {
private PreferenceHeader[] getPreferenceHeaders() {
return new PreferenceHeader[] {
newPreferenceHeader(
R.drawable.ic_cellphone_android_theme_accent,
R.string.settings_display,
@@ -51,7 +52,6 @@ public final class MainSettingsScene extends PreferenceHeaderScene {
R.string.settings_advance,
AdvanceSettingsScene.class)
};
setPreferenceHeaders(phs);
}
@Override
@@ -16,8 +16,6 @@
package com.hippo.ehviewer.ui.scene;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
@@ -61,8 +59,8 @@ public final class SignInScene extends Scene implements View.OnClickListener,
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setContentView(R.layout.scene_sign_in);
mMainView = findViewById(R.id.sigin_in_main);
@@ -17,9 +17,7 @@
package com.hippo.scene;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.View;
import android.view.ViewGroup;
@@ -53,8 +51,8 @@ public class AppbarScene extends Scene {
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
super.setContentView(R.layout.scene_appbar);
mIcon = (SimpleImageView) super.findViewById(R.id.appbar_icon);
+10 -6
View File
@@ -18,9 +18,6 @@ package com.hippo.scene;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.hippo.util.ViewUtils;
public abstract class Curtain {
@@ -38,6 +35,13 @@ public abstract class Curtain {
return scene != null && scene.getId() == mPreviousSceneId;
}
/**
* @return true if can NOT still run when previous scene changed
*/
protected boolean specifyPreviousScene() {
return true;
}
protected void onRebirth() {
}
@@ -62,7 +66,7 @@ public abstract class Curtain {
public abstract boolean isInAnimation();
protected void dispatchOpenFinished(@NonNull Scene enter, @NonNull Scene exit) {
exit.openFinished();
enter.openFinished();
}
protected void dispatchCloseFinished(@NonNull Scene enter, @NonNull Scene exit) {
@@ -70,10 +74,10 @@ public abstract class Curtain {
}
protected void hideSceneOnOpen(@NonNull Scene exit) {
ViewUtils.setVisibility(exit.getSceneView(), View.GONE);
exit.setHide(true);
}
protected void showSceneOnClose(@NonNull Scene enter) {
ViewUtils.setVisibility(enter.getSceneView(), View.VISIBLE);
enter.setHide(false);
}
}
+141 -75
View File
@@ -39,34 +39,38 @@ import com.hippo.util.ViewUtils;
* When start a new {@code Scene}, previous {@code Scene} can stay at screen for
* a while. Or retain for a while before destroy.
*/
// TODO Improve state
public abstract class Scene {
public static final int LAUNCH_MODE_STANDARD = 0;
public static final int LAUNCH_MODE_SINGLE_TOP = 1;
static final int SCENE_STATE_CREATE = 0;
static final int SCENE_STATE_RUN = 1;
static final int SCENE_STATE_DESTROY = 2;
static final int SCENE_STATE_OPEN = 3;
static final int SCENE_STATE_INIT = 0;
static final int SCENE_STATE_PREPARE = 1;
static final int SCENE_STATE_OPEN = 2;
static final int SCENE_STATE_RUN = 3;
static final int SCENE_STATE_CLOSE = 4;
static final int SCENE_STATE_PAUSE = 5;
static final int SCENE_STATE_DESTROY = 5;
static final int SCENE_STATE_DIE = 6;
static final int SCENE_STATE_PAUSE = 7;
static final int SCENE_STATE_REBIRTH = 8;
private @Nullable Curtain mCurtain;
private @Nullable Announcer mAnnouncer;
@SuppressWarnings("deprecation")
private @Nullable SceneView mSceneView;
private SceneView mSceneView;
private int mBackgroundColor = 0xffeeeeee; // TODO Need a better to set background color
private int mState;
private int mState = SCENE_STATE_INIT;
protected static SceneManager sSceneManager;
private int mId;
private boolean mHide;
static void setSceneManager(SceneManager sceneManager) {
sSceneManager = sceneManager;
}
@@ -106,11 +110,15 @@ public abstract class Scene {
return LAUNCH_MODE_STANDARD;
}
private void checkSceneView() {
AssertUtils.assertNotNull("Must call it after onCreate and before onDestroy", mSceneView);
}
/**
* Must call it after onCreate and before onDestroy
*/
public @NonNull SceneView getSceneView() {
AssertUtils.assertNotNull("Must call it after onCreate and before onDestroy", mSceneView);
checkSceneView();
return mSceneView;
}
@@ -143,10 +151,37 @@ public abstract class Scene {
sSceneManager.finishScene(this);
}
void create(@Nullable Bundle savedInstanceState) {
onCreate(savedInstanceState);
void setHide(boolean hide) {
checkSceneView();
mHide = hide;
if (hide) {
mSceneView.setVisibility(View.GONE);
} else {
mSceneView.setVisibility(View.VISIBLE);
}
}
boolean getHide() {
return mHide;
}
void init() {
onInit();
}
void rebirth() {
if (mCurtain != null) {
mCurtain.onRebirth();
}
onRebirth();
}
void create(boolean rebirth) {
onCreate(rebirth);
if (mSceneView == null) {
// Not call setContentView in onCreate, create scene view by ourself
mSceneView = createSceneView(getStageActivity());
initBackground(mSceneView);
}
@@ -155,24 +190,56 @@ public abstract class Scene {
attachToStage();
// Hide it if it is hidden
if (savedInstanceState != null && savedInstanceState.getBoolean(getIsGoneKey(), false)) {
if (mHide) {
mSceneView.setVisibility(View.INVISIBLE);
mSceneView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewUtils.removeOnGlobalLayoutListener(mSceneView.getViewTreeObserver(), this);
ViewUtils.setVisibility(mSceneView, View.GONE);
mSceneView.setVisibility(View.GONE);
}
});
}
}
// TODO Tell destory is it need close
void destroy() {
onDestroy();
void bind() {
onBind();
}
void restore() {
onRestore();
}
void destroy(boolean die) {
// Make sure soft key broad is hidden
InputMethodManager imm = (InputMethodManager) getStageActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getSceneView().getWindowToken(), 0);
onDestroy(die);
}
void die(boolean keepView) {
onDie();
if (!keepView) {
detachFromeStage();
}
SceneApplication.getRefWatcher(getStageActivity()).watch(this);
}
void pause() {
getSceneView().setEnableTouch(false);
onPause();
}
void resume() {
getSceneView().setEnableTouch(true);
onResume();
}
void open() {
onOpen();
}
@@ -181,16 +248,48 @@ public abstract class Scene {
onClose();
}
void pause() {
onPause();
protected void onInit() {
}
void resume() {
onResume();
protected void onRebirth() {
}
void rebirth(@Nullable Bundle savedInstanceState) {
onRebirth(savedInstanceState);
protected void onCreate(boolean rebirth) {
}
protected void onBind() {
}
protected void onRestore() {
}
protected void onDestroy(boolean die) {
}
protected void onDie() {
}
protected void onPause() {
}
protected void onResume() {
}
protected void onOpen() {
}
protected void onClose() {
}
void setFitPaddingBottom(int b) {
@@ -198,10 +297,21 @@ public abstract class Scene {
}
/**
* return true if it is close or about to close
* @return true if the scene is dead or will be
*/
public boolean isFinishing() {
return mState == SCENE_STATE_CLOSE || mState == SCENE_STATE_DESTROY;
public boolean canNotBeSaved() {
return mState == SCENE_STATE_CLOSE || mState == SCENE_STATE_DESTROY || mState == SCENE_STATE_DIE;
}
/**
* @return true if the scene is dead
*/
public boolean isDead() {
return mState == SCENE_STATE_DIE;
}
public boolean isRunning() {
return mState == SCENE_STATE_RUN;
}
public void setBackgroundColor(int bgColor) {
@@ -230,7 +340,8 @@ public abstract class Scene {
StageActivity sa = getStageActivity();
mSceneView = createSceneView(sa);
initBackground(mSceneView);
mSceneView.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mSceneView.addView(view, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
private void initBackground(@NonNull View bg) {
@@ -240,38 +351,6 @@ public abstract class Scene {
bg.requestFocus();
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
}
@SuppressWarnings("ConstantConditions")
protected void onDestroy() {
// Make sure soft key broad is hidden
if (mSceneView != null) {
InputMethodManager imm = (InputMethodManager) getStageActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSceneView.getWindowToken(), 0);
}
}
protected void onOpen() {
}
protected void onClose() {
}
protected void onPause() {
getSceneView().setEnableTouch(false);
}
protected void onResume() {
getSceneView().setEnableTouch(true);
}
protected void onRebirth(@Nullable Bundle savedInstanceState) {
if (mCurtain != null) {
mCurtain.onRebirth();
}
}
protected void onNewAnnouncer(Announcer announcer) {
}
@@ -369,16 +448,11 @@ public abstract class Scene {
}
void openFinished() {
open();
setState(Scene.SCENE_STATE_RUN);
sSceneManager.openScene(this);
}
void closeFinished() {
sSceneManager.removeLegacyScene(this);
close();
setState(Scene.SCENE_STATE_DESTROY);
detachFromeStage();
sSceneManager.closeScene(this);
}
// It is constant
@@ -386,21 +460,13 @@ public abstract class Scene {
return "scene:" + mId;
}
private String getIsGoneKey() {
return getStateKey() + ":gone";
}
protected void saveInstanceState(Bundle outState) {
void saveInstanceState(Bundle outState) {
SparseArray<Parcelable> states = new SparseArray<>();
onSaveInstanceState(states);
outState.putSparseParcelableArray(getStateKey(), states);
if (mSceneView != null) {
outState.putBoolean(getIsGoneKey(), mSceneView.getVisibility() == View.GONE);
}
}
protected void restoreInstanceState(@NonNull Bundle savedInstanceState) {
void restoreInstanceState(@NonNull Bundle savedInstanceState) {
if (mSceneView != null) {
SparseArray<Parcelable> savedStates
= savedInstanceState.getSparseParcelableArray(getStateKey());
@@ -17,14 +17,18 @@
package com.hippo.scene;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.hippo.util.AssertUtils;
import com.hippo.util.IntIdGenerator;
import com.hippo.util.Log;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class SceneManager {
@@ -34,7 +38,9 @@ public class SceneManager {
private Stack<Scene> mSceneStack = new Stack<>();
private StageActivity mStageActivity;
private Scene mLegacyScene;
private boolean mLegacySceneSetLock;
private Set<Scene> mLegacySceneSet = new HashSet<>();
private Set<Scene> mPrepareToDieSceneSet = new HashSet<>();
private IntIdGenerator mIdGenerator = IntIdGenerator.create();
@@ -107,6 +113,19 @@ public class SceneManager {
}
}
private void checkLoop() {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("It is not main loop!");
}
}
private void checkPrepareToDie(Scene scene) {
if (mPrepareToDieSceneSet.contains(scene)) {
mPrepareToDieSceneSet.remove(scene);
finishScene(scene);
}
}
Scene createSceneByClass(@NonNull Class sceneClass) {
try {
return (Scene) sceneClass.newInstance();
@@ -123,12 +142,14 @@ public class SceneManager {
// TODO check previousState state
void startScene(@NonNull Class sceneClass, @Nullable Announcer announcer,
@Nullable Curtain curtain) {
checkLoop();
if (!isStageAlive()) {
Log.w(TAG, "Stage is not alive, but attemp to create " + sceneClass.getSimpleName());
return;
throw new IllegalStateException("Stage is not alive, but attemp to create " + sceneClass.getSimpleName());
}
Scene topScene = getTopState();
// check LAUNCH_MODE_SINGLE_TOP
Scene topScene = getTopScene();
if (sceneClass.isInstance(topScene) &&
topScene.getLaunchMode() == Scene.LAUNCH_MODE_SINGLE_TOP) {
topScene.onNewAnnouncer(announcer);
@@ -143,6 +164,8 @@ public class SceneManager {
}
void showDialog(@NonNull SceneDialog dialog, @Nullable Curtain curtain) {
checkLoop();
if (!isStageAlive()) {
Log.w(TAG, "Stage is not alive, but attemp to show dialog " + dialog.toString());
return;
@@ -154,7 +177,7 @@ public class SceneManager {
}
private void startScene(Scene scene, Curtain curtain) {
Scene previousState = getTopState();
Scene previousState = getTopScene();
mSceneStack.push(scene);
if (curtain != null) {
@@ -164,12 +187,12 @@ public class SceneManager {
if (previousState != null) {
previousState.pause();
previousState.setState(Scene.SCENE_STATE_PAUSE);
notifyPause(previousState.getClass());
}
scene.create(null);
scene.setState(Scene.SCENE_STATE_CREATE);
notifyCreate(scene.getClass());
scene.init();
scene.setState(Scene.SCENE_STATE_PREPARE);
scene.create(false);
scene.bind();
// Update fit padding
int fitPaddingBottom = getStageActivity().getFitPaddingBottom();
@@ -183,65 +206,80 @@ public class SceneManager {
// Set state run by curtain
} else {
scene.setState(Scene.SCENE_STATE_RUN);
checkPrepareToDie(scene);
}
}
/**
* End legacy scene close animation at once
* End all legacy scene animation at once
*
* @return True if legacy scene exist and its curtain animation is running
*/
boolean endLegacyScene() {
if (mLegacyScene != null) {
boolean result = mLegacyScene.endCurtainAnimation();
mLegacyScene = null;
return result;
if (!mLegacySceneSet.isEmpty()) {
mLegacySceneSetLock = true;
for (Scene scene : mLegacySceneSet) {
scene.endCurtainAnimation();
}
mLegacySceneSetLock = false;
mLegacySceneSet.clear();
return true;
} else {
return false;
}
return false;
}
void finishScene(@NonNull Scene scene) {
checkLoop();
int index = getSceneIndex(scene);
if (index >= 0 && index < mSceneStack.size()) {
if (scene.canNotBeSaved()) {
// the scene is hopeless
scene.endCurtainAnimation();
return;
}
endLegacyScene();
if (!scene.isRunning()) {
// the scene prepare to die
mPrepareToDieSceneSet.add(scene);
scene.endCurtainAnimation();
return;
}
// Scene state might be SCENE_STATE_RUN, SCENE_STATE_OPEN, SCENE_STATE_PAUSE
if (index == 0) {
// TODO If the cene is under a dialog, the previous may not show
if (index != mSceneStack.size() - 1 || index == 0) {
// It is the last scene, just finish the activity
mSceneStack.remove(index);
scene.destroy();
scene.destroy(true);
scene.setState(Scene.SCENE_STATE_DESTROY);
notifyDestroy(scene.getClass());
scene.die(index == 0);
scene.setState(Scene.SCENE_STATE_DIE);
getStageActivity().finish();
} else {
// TODO check scene state
mSceneStack.remove(index);
Scene previousState = getTopState();
// If Scene is CLOSE
if (previousState != null) {
previousState.resume();
previousState.setState(Scene.SCENE_STATE_RUN);
notifyResume(previousState.getClass());
if (index == 0) {
getStageActivity().finish();
}
} else {
mSceneStack.remove(index);
Scene previousScene = mSceneStack.get(index - 1);
scene.destroy();
scene.setState(Scene.SCENE_STATE_DESTROY);
notifyDestroy(scene.getClass());
previousScene.resume();
previousScene.setState(Scene.SCENE_STATE_RUN);
scene.destroy(true);
Curtain curtain = scene.getCurtain();
if (curtain != null && previousState != null && curtain.isPreviousScene(previousState)) {
if (curtain != null &&
(!curtain.specifyPreviousScene() || curtain.isPreviousScene(previousScene))) {
scene.setState(Scene.SCENE_STATE_CLOSE);
mLegacyScene = scene;
curtain.close(previousState, scene);
// detachFromeStage by curtain
curtain.close(previousScene, scene);
// add the scene to legacy set
mLegacySceneSet.add(scene);
// curtain will kill the scene
} else {
scene.detachFromeStage();
scene.setState(Scene.SCENE_STATE_DESTROY);
scene.die(false);
scene.setState(Scene.SCENE_STATE_DIE);
}
}
} else {
@@ -249,9 +287,28 @@ public class SceneManager {
}
}
void removeLegacyScene(Scene scene) {
if (mLegacyScene == scene) {
mLegacyScene = null;
private void checkSceneState(Scene scene, int expected) {
AssertUtils.assertEquals("The scene state is " + scene.getState() + ", but it should be " + expected,
expected, scene.getState());
}
void openScene(Scene scene) {
checkSceneState(scene, Scene.SCENE_STATE_OPEN);
scene.open();
scene.setState(Scene.SCENE_STATE_RUN);
checkPrepareToDie(scene);
}
void closeScene(Scene scene) {
checkSceneState(scene, Scene.SCENE_STATE_CLOSE);
scene.close();
scene.setState(Scene.SCENE_STATE_DESTROY);
scene.die(false);
scene.setState(Scene.SCENE_STATE_DIE);
// remove the scene from legacy set
if (!mLegacySceneSetLock) {
mLegacySceneSet.remove(scene);
}
}
@@ -266,7 +323,7 @@ public class SceneManager {
}
boolean onBackPressed() {
Scene scene = getTopState();
Scene scene = getTopScene();
if (scene != null) {
scene.onBackPressedInternal();
return true;
@@ -276,7 +333,7 @@ public class SceneManager {
}
}
private Scene getTopState() {
private Scene getTopScene() {
if (!mSceneStack.isEmpty()) {
return mSceneStack.peek();
} else {
@@ -296,10 +353,13 @@ public class SceneManager {
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
for (Scene scene : mSceneStack) {
// Recreate
scene.rebirth(savedInstanceState);
notifyRebirth(scene.getClass());
scene.create(savedInstanceState);
scene.destroy(false);
scene.setState(Scene.SCENE_STATE_REBIRTH);
scene.rebirth();
scene.setState(Scene.SCENE_STATE_PREPARE);
scene.create(true);
scene.restore();
scene.setState(Scene.SCENE_STATE_RUN);
scene.restoreInstanceState(savedInstanceState);
}
}
@@ -17,7 +17,6 @@
package com.hippo.scene;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -72,8 +71,8 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
// TODO
setBackgroundColor(BACKGROUND_COLOR);
@@ -103,8 +102,8 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
}
@Override
protected void onDestroy() {
super.onDestroy();
protected void onDie() {
super.onDie();
OnCloseListener listener = mBuilder.mOnCloseListener;
if (listener != null) {
@@ -16,7 +16,6 @@
package com.hippo.scene.preference;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@@ -49,8 +48,8 @@ public class PreferenceHeaderScene extends AppbarScene {
private List<PreferenceHeader> mHeaderList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setContentView(R.layout.scene_preference_header);
mActivity = getStageActivity();
@@ -16,7 +16,6 @@
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;
@@ -45,8 +44,8 @@ public class PreferenceScene extends AppbarScene {
private List<PreferenceBase> mPreferenceBaseList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
setContentView(R.layout.scene_preference);
mRecyclerView = (EasyRecyclerView) findViewById(R.id.recycler_view);