/* * Copyright (C) 2015 Hippo Seven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hippo.scene; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewTreeObserver; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; import com.hippo.util.AssertUtils; import com.hippo.util.ViewUtils; import java.util.Map; /** * {@link com.hippo.scene.Scene} is a {@code Activity} of {@link android.app.Activity}. *
* When start a new {@code Scene}, previous {@code Scene} can stay at screen for
* a while. Or retain for a while before destroy.
*/
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_CLOSE = 4;
static final int SCENE_STATE_PAUSE = 5;
private @Nullable Curtain mCurtain;
private @Nullable Announcer mAnnouncer;
@SuppressWarnings("deprecation")
private @Nullable SceneView mSceneView;
private int mBackgroundColor = 0xffeeeeee; // TODO Need a better to set background color
private int mState;
protected static SceneManager sSceneManager;
private int mId;
static void setSceneManager(SceneManager sceneManager) {
sSceneManager = sceneManager;
}
public Scene() {
mId = sSceneManager.nextId();
}
int getId() {
return mId;
}
void setCurtain(@Nullable Curtain curtain) {
mCurtain = curtain;
}
void setAnnouncer(@Nullable Announcer announcer) {
mAnnouncer = announcer;
}
@Nullable Curtain getCurtain() {
return mCurtain;
}
public @Nullable Announcer getAnnouncer() {
return mAnnouncer;
}
// If there is no StageActivity for SceneManager, yout will get AssertError
public @NonNull StageActivity getStageActivity() {
StageActivity stageActivity = sSceneManager.getStageActivity();
AssertUtils.assertNotNull("StageActivity is null", stageActivity);
return stageActivity;
}
public int getLaunchMode() {
return LAUNCH_MODE_STANDARD;
}
/**
* Must call it after onCreate and before onDestroy
*/
public @NonNull SceneView getSceneView() {
AssertUtils.assertNotNull("Must call it after onCreate and before onDestroy", mSceneView);
return mSceneView;
}
public void startScene(@NonNull Class sceneClass) {
sSceneManager.startScene(sceneClass, null, null);
}
public void startScene(@NonNull Class sceneClass, @Nullable Announcer announcer) {
sSceneManager.startScene(sceneClass, announcer, null);
}
public void startScene(@NonNull Class sceneClass, @Nullable Announcer announcer,
@Nullable Curtain curtain) {
sSceneManager.startScene(sceneClass, announcer, curtain);
}
int getState() {
return mState;
}
void setState(int state) {
mState = state;
}
protected SceneView createSceneView(Context context) {
return new SceneView(context);
}
public final void finish() {
sSceneManager.finishScene(this);
}
void create(@Nullable Bundle savedInstanceState) {
onCreate(savedInstanceState);
if (mSceneView == null) {
mSceneView = createSceneView(getStageActivity());
initBackground(mSceneView);
}
// Make sure scene view is attach from stage
attachToStage();
// Hide it if it is hidden
if (savedInstanceState != null && savedInstanceState.getBoolean(getIsGoneKey(), false)) {
mSceneView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewUtils.removeOnGlobalLayoutListener(mSceneView.getViewTreeObserver(), this);
ViewUtils.setVisibility(mSceneView, View.GONE);
}
});
}
}
// TODO Tell destory is it need close
void destroy(boolean willSave) {
onDestroy(willSave);
SceneApplication.getRefWatcher(getStageActivity()).watch(this);
}
void open() {
onOpen();
}
void close() {
onClose();
}
void pause() {
onPause();
}
void resume() {
onResume();
}
void save(Map