From 006788ea2e84b6060bdc295d0615ab8a5a8dc30f Mon Sep 17 00:00:00 2001 From: seven332 Date: Wed, 16 Mar 2016 01:44:05 +0800 Subject: [PATCH] Improve scene render order --- .../java/com/hippo/scene/SceneFragment.java | 14 +++-- .../java/com/hippo/scene/StageActivity.java | 53 +++++++++++++---- .../java/com/hippo/scene/StageLayout.java | 59 +++++++++++-------- 3 files changed, 87 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/hippo/scene/SceneFragment.java b/app/src/main/java/com/hippo/scene/SceneFragment.java index 6ed1a1022..a281cf929 100644 --- a/app/src/main/java/com/hippo/scene/SceneFragment.java +++ b/app/src/main/java/com/hippo/scene/SceneFragment.java @@ -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) { diff --git a/app/src/main/java/com/hippo/scene/StageActivity.java b/app/src/main/java/com/hippo/scene/StageActivity.java index 47963b569..832a7663e 100644 --- a/app/src/main/java/com/hippo/scene/StageActivity.java +++ b/app/src/main/java/com/hippo/scene/StageActivity.java @@ -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 mSceneTagList = new ArrayList<>(); + private final ArrayList mSceneTagList = new ArrayList<>(); + private final ArrayList 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 { + + 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, 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 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 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; diff --git a/app/src/main/java/com/hippo/scene/StageLayout.java b/app/src/main/java/com/hippo/scene/StageLayout.java index 3befd8469..624cf8535 100644 --- a/app/src/main/java/com/hippo/scene/StageLayout.java +++ b/app/src/main/java/com/hippo/scene/StageLayout.java @@ -32,6 +32,7 @@ public class StageLayout extends FrameLayout { private Field mDisappearingChildrenField; private ArrayList mSuperDisappearingChildren; + private ArrayList 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 disappearingChildren = mSuperDisappearingChildren; + ArrayList 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 disappearingChildren = mSuperDisappearingChildren; - if (mDoTrick) { + ArrayList 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; }