Improve scene render order

This commit is contained in:
seven332 committed 2016-03-16 01:44:05 +08:00
1 parent e071599391
commit 006788ea2e
3 files changed
+87 -39

No files matched your search

@@ -25,7 +25,6 @@ import android.support.v4.app.FragmentActivity;
import android.view.View;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.yorozuya.IntList;
import java.lang.annotation.Retention;
@@ -87,7 +86,7 @@ public class SceneFragment extends Fragment {
public int getStackIndex() {
FragmentActivity activity = getActivity();
if (activity instanceof StageActivity) {
return ((StageActivity) activity).getStackIndex(this);
return ((StageActivity) activity).getSceneIndex(this);
} else {
return -1;
}
@@ -105,7 +104,7 @@ public class SceneFragment extends Fragment {
view.setBackgroundColor(getContext().getResources().getColor(R.color.background_light));
// Notify
((MainActivity) getActivity()).onSceneViewCreated(this, savedInstanceState);
((StageActivity) getActivity()).onSceneViewCreated(this, savedInstanceState);
}
@Override
@@ -113,7 +112,14 @@ public class SceneFragment extends Fragment {
super.onDestroyView();
// Notify
((MainActivity) getActivity()).onSceneViewDestroyed(this);
((StageActivity) getActivity()).onSceneViewDestroyed(this);
}
@Override
public void onDestroy() {
super.onDestroy();
((StageActivity) getActivity()).onSceneDestroyed(this);
}
void addRequest(String requestSceneTag, int requestCode) {
@@ -24,6 +24,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.TrackedActivity;
@@ -31,7 +32,10 @@ import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.IntIdGenerator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -48,11 +52,31 @@ public abstract class StageActivity extends TrackedActivity {
private static final String KEY_SCENE_TAG_LIST = "stage_activity_scene_tag_list";
private static final String KEY_NEXT_ID = "stage_activity_next_id";
private ArrayList<String> mSceneTagList = new ArrayList<>();
private final ArrayList<String> mSceneTagList = new ArrayList<>();
private final ArrayList<String> mDelaySceneTagList = new ArrayList<>();
private final AtomicInteger mIdGenerator = new AtomicInteger();
private int mStageId = IntIdGenerator.INVALID_ID;
private final SceneViewComparator mSceneViewComparator = new SceneViewComparator();
private final class SceneViewComparator implements Comparator<View> {
private int getIndex(View view) {
Object o = view.getTag(R.id.fragment_tag);
if (o instanceof String) {
return mDelaySceneTagList.indexOf(o);
} else {
return -1;
}
}
@Override
public int compare(View lhs, View rhs) {
return getIndex(lhs) - getIndex(rhs);
}
}
private static final Map<Class<?>, Integer> sLaunchModeMap = new HashMap<>();
public static void registerLaunchMode(Class<?> clazz, @SceneFragment.LaunchMode int launchMode) {
@@ -138,7 +162,9 @@ public abstract class StageActivity extends TrackedActivity {
if (savedInstanceState != null) {
mStageId = savedInstanceState.getInt(KEY_STAGE_ID, IntIdGenerator.INVALID_ID);
mSceneTagList = savedInstanceState.getStringArrayList(KEY_SCENE_TAG_LIST);
ArrayList<String> list = savedInstanceState.getStringArrayList(KEY_SCENE_TAG_LIST);
mSceneTagList.addAll(list);
mDelaySceneTagList.addAll(list);
mIdGenerator.lazySet(savedInstanceState.getInt(KEY_NEXT_ID));
}
@@ -193,6 +219,10 @@ public abstract class StageActivity extends TrackedActivity {
public void onSceneViewDestroyed(SceneFragment scene) {
}
void onSceneDestroyed(SceneFragment scene) {
mDelaySceneTagList.remove(scene.getTag());
}
protected void onRegister(int id) {
mStageId = id;
}
@@ -321,6 +351,7 @@ public abstract class StageActivity extends TrackedActivity {
// Add new tag to list
mSceneTagList.add(newTag);
mDelaySceneTagList.add(newTag);
FragmentTransaction transaction = fragmentManager.beginTransaction();
// Animation
@@ -420,6 +451,7 @@ public abstract class StageActivity extends TrackedActivity {
// Add tag to list
mSceneTagList.add(tag);
mDelaySceneTagList.add(tag);
// Add scene
transaction.add(getContainerViewId(), scene, tag);
@@ -434,19 +466,16 @@ public abstract class StageActivity extends TrackedActivity {
}
}
int getStackIndex(SceneFragment scene) {
return getStackIndex(scene.getTag());
int getSceneIndex(SceneFragment scene) {
return getTagIndex(scene.getTag());
}
int getStackIndex(String tag) {
return mSceneTagList.indexOf(tag); // Collections.binarySearch(mSceneTagList, tag);
int getTagIndex(String tag) {
return mSceneTagList.indexOf(tag);
}
// TODO What about id is negative
int compareScene(String tag1, String tag2) throws NumberFormatException {
int int1 = Integer.parseInt(tag1);
int int2 = Integer.parseInt(tag2);
return int1 - int2;
void sortSceneViews(List<View> views) {
Collections.sort(views, mSceneViewComparator);
}
public void finishScene(SceneFragment scene) {
@@ -468,7 +497,7 @@ public abstract class StageActivity extends TrackedActivity {
}
// Get scene index
int index = mSceneTagList.indexOf(tag);//Collections.binarySearch(mSceneTagList, tag);
int index = mSceneTagList.indexOf(tag);
if (index < 0) {
Log.e(TAG, "finishScene: Can't find the tag in tag list: " + tag);
return;
@@ -32,6 +32,7 @@ public class StageLayout extends FrameLayout {
private Field mDisappearingChildrenField;
private ArrayList<View> mSuperDisappearingChildren;
private ArrayList<View> mSortedScenes;
private View mDumpView;
private boolean mDoTrick;
@@ -77,23 +78,15 @@ public class StageLayout extends FrameLayout {
}
}
private String getViewTag(View view) {
Object tag = view.getTag(R.id.fragment_tag);
if (tag instanceof String) {
return (String) tag;
} else {
return null;
}
}
private boolean beforeDispatchDraw() {
getSuperDisappearingChildren();
if (mSuperDisappearingChildren == null ||
mSuperDisappearingChildren.size() <= 0 || getChildCount() <= 1) { // dump view
mSuperDisappearingChildren.size() <= 0 || getChildCount() <= 1) { // only dump view
return false;
}
// Get stage
StageActivity stage = null;
Context context = getContext();
if (context instanceof StageActivity) {
@@ -103,14 +96,34 @@ public class StageLayout extends FrameLayout {
return false;
}
View view1 = mSuperDisappearingChildren.get(0);
View view2 = getChildAt(1); // Skip dump view
String tag1 = getViewTag(view1);
String tag2 = getViewTag(view2);
try {
return stage.compareScene(tag1, tag2) < 0;
} catch (NumberFormatException e) {
return false;
if (null == mSortedScenes) {
mSortedScenes = new ArrayList<>();
}
// Add all scene view to mSortedScenes
ArrayList<View> disappearingChildren = mSuperDisappearingChildren;
ArrayList<View> sortedScenes = mSortedScenes;
for (int i = 1, n = getChildCount(); i < n; i++) { // Skip dump view
View view = getChildAt(i);
if (null != view.getTag(R.id.fragment_tag)) {
sortedScenes.add(view);
}
}
for (int i = 0, n = disappearingChildren.size(); i < n; i++) {
View view = disappearingChildren.get(i);
if (null != view.getTag(R.id.fragment_tag)) {
sortedScenes.add(view);
}
}
stage.sortSceneViews(sortedScenes);
return true;
}
private void afterDispatchDraw() {
if (null != mSortedScenes) {
mSortedScenes.clear();
}
}
@@ -118,21 +131,21 @@ public class StageLayout extends FrameLayout {
protected void dispatchDraw(Canvas canvas) {
mDoTrick = beforeDispatchDraw();
super.dispatchDraw(canvas);
afterDispatchDraw();
mDoTrick = false;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
ArrayList<View> disappearingChildren = mSuperDisappearingChildren;
if (mDoTrick) {
ArrayList<View> sortedScenes = mSortedScenes;
if (child == mDumpView) {
boolean more = false;
for (int i = disappearingChildren.size() - 1; i >= 0; i--) {
more |= super.drawChild(canvas, disappearingChildren.get(i), drawingTime);
for (int i = 0, n = sortedScenes.size(); i < n; i++) {
more |= super.drawChild(canvas, sortedScenes.get(i), drawingTime);
}
return more;
} else if (disappearingChildren.contains(child)) {
} else if (sortedScenes.contains(child)) {
// Skip
return false;
}