Improve scene lifecycle
This commit is contained in:
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user