From 9925abf40fda11fa99edba22abdbac3bd01758b0 Mon Sep 17 00:00:00 2001 From: seven332 Date: Sun, 31 Jan 2016 15:21:48 +0800 Subject: [PATCH] Do trick to draw disappearing children first --- .../java/com/hippo/scene/SceneFragment.java | 12 ++ .../java/com/hippo/scene/StageActivity.java | 10 +- .../java/com/hippo/scene/StageLayout.java | 143 ++++++++++++++++++ ...ccelerate_terz.xml => decelerate_terz.xml} | 2 +- app/src/main/res/anim/scene_close_enter.xml | 4 +- app/src/main/res/anim/scene_open_exit.xml | 9 +- app/src/main/res/layout/activity_main.xml | 3 +- app/src/main/res/values-v21/themes.xml | 2 +- app/src/main/res/values/colors.xml | 3 + app/src/main/res/values/ids.xml | 22 +++ app/src/main/res/values/themes.xml | 14 +- 11 files changed, 210 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/com/hippo/scene/StageLayout.java rename app/src/main/res/anim/{accelerate_terz.xml => decelerate_terz.xml} (96%) create mode 100644 app/src/main/res/values/ids.xml diff --git a/app/src/main/java/com/hippo/scene/SceneFragment.java b/app/src/main/java/com/hippo/scene/SceneFragment.java index 607bfb61f..f2e757d3b 100644 --- a/app/src/main/java/com/hippo/scene/SceneFragment.java +++ b/app/src/main/java/com/hippo/scene/SceneFragment.java @@ -19,8 +19,12 @@ package com.hippo.scene; import android.os.Bundle; import android.support.annotation.IntDef; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; +import android.view.View; + +import com.hippo.ehviewer.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -97,4 +101,12 @@ public class SceneFragment extends Fragment { public boolean onBackPressed() { return false; } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + view.setTag(R.id.fragment_tag, getTag()); + view.setBackgroundColor(getContext().getResources().getColor(R.color.background_light)); + } } diff --git a/app/src/main/java/com/hippo/scene/StageActivity.java b/app/src/main/java/com/hippo/scene/StageActivity.java index 6e06cdfc0..3f0e68a57 100644 --- a/app/src/main/java/com/hippo/scene/StageActivity.java +++ b/app/src/main/java/com/hippo/scene/StageActivity.java @@ -28,7 +28,6 @@ import com.hippo.ehviewer.R; import com.hippo.yorozuya.IntIdGenerator; import java.util.ArrayList; -import java.util.Collections; public abstract class StageActivity extends AppCompatActivity { @@ -148,7 +147,14 @@ public abstract class StageActivity extends AppCompatActivity { } int getStackIndex(String tag) { - return Collections.binarySearch(mSceneTagList, tag); + return mSceneTagList.indexOf(tag); // Collections.binarySearch(mSceneTagList, 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; } public void finishScene(SceneFragment scene) { diff --git a/app/src/main/java/com/hippo/scene/StageLayout.java b/app/src/main/java/com/hippo/scene/StageLayout.java new file mode 100644 index 000000000..59ffd7258 --- /dev/null +++ b/app/src/main/java/com/hippo/scene/StageLayout.java @@ -0,0 +1,143 @@ +/* + * Copyright 2016 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.graphics.Canvas; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.hippo.ehviewer.R; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +public class StageLayout extends FrameLayout { + + private Field mDisappearingChildrenField; + private ArrayList mSuperDisappearingChildren; + private View mDumpView; + private boolean mDoTrick; + + public StageLayout(Context context) { + super(context); + init(context); + } + + public StageLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public StageLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + try { + mDisappearingChildrenField = ViewGroup.class.getDeclaredField("mDisappearingChildren"); + mDisappearingChildrenField.setAccessible(true); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + + if (mDisappearingChildrenField != null) { + mDumpView = new View(context); + addView(mDumpView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + } + } + + @SuppressWarnings("unchecked") + private void getSuperDisappearingChildren() { + if (mDisappearingChildrenField == null || mSuperDisappearingChildren != null) { + return; + } + + try { + mSuperDisappearingChildren = (ArrayList) mDisappearingChildrenField.get(this); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + 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 + return false; + } + + StageActivity stage = null; + Context context = getContext(); + if (context instanceof StageActivity) { + stage = (StageActivity) context; + } + if (stage == null) { + return false; + } + + View view1 = mSuperDisappearingChildren.get(0); + View view2 = getChildAt(1); // dump view + String tag1 = getViewTag(view1); + String tag2 = getViewTag(view2); + try { + return stage.compareScene(tag1, tag2) < 0; + } catch (NumberFormatException e) { + return false; + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + mDoTrick = beforeDispatchDraw(); + super.dispatchDraw(canvas); + mDoTrick = false; + } + + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + ArrayList disappearingChildren = mSuperDisappearingChildren; + + if (mDoTrick && disappearingChildren != null && disappearingChildren.size() > 0) { + if (child == mDumpView) { + boolean more = false; + for (int i = disappearingChildren.size() - 1; i >= 0; i--) { + more |= super.drawChild(canvas, disappearingChildren.get(i), drawingTime); + } + return more; + } else if (disappearingChildren.contains(child)) { + // Skip + return false; + } + } + + return super.drawChild(canvas, child, drawingTime); + } +} diff --git a/app/src/main/res/anim/accelerate_terz.xml b/app/src/main/res/anim/decelerate_terz.xml similarity index 96% rename from app/src/main/res/anim/accelerate_terz.xml rename to app/src/main/res/anim/decelerate_terz.xml index 1ac8e476c..b8289000d 100644 --- a/app/src/main/res/anim/accelerate_terz.xml +++ b/app/src/main/res/anim/decelerate_terz.xml @@ -15,6 +15,6 @@ ~ limitations under the License. --> - diff --git a/app/src/main/res/anim/scene_close_enter.xml b/app/src/main/res/anim/scene_close_enter.xml index 16a51fc9c..8468ce8aa 100644 --- a/app/src/main/res/anim/scene_close_enter.xml +++ b/app/src/main/res/anim/scene_close_enter.xml @@ -19,12 +19,12 @@ xmlns:android="http://schemas.android.com/apk/res/android"> diff --git a/app/src/main/res/anim/scene_open_exit.xml b/app/src/main/res/anim/scene_open_exit.xml index dc0136110..6d2a3f2fa 100644 --- a/app/src/main/res/anim/scene_open_exit.xml +++ b/app/src/main/res/anim/scene_open_exit.xml @@ -16,16 +16,15 @@ --> + xmlns:android="http://schemas.android.com/apk/res/android"> + android:duration="217"/> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 98aa01f70..39b8a921e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -22,7 +22,7 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml index 85dd461d6..f04730d85 100644 --- a/app/src/main/res/values-v21/themes.xml +++ b/app/src/main/res/values-v21/themes.xml @@ -17,7 +17,7 @@ - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 8afe1cf2d..718e32cd1 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -36,6 +36,9 @@ #61ffffff #24000000 + #ff303030 + #fffafafa + #fff44336 #ff009688 #ff00796b diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 000000000..2e7c97009 --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index ee30064dd..76bfe809e 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -24,12 +24,22 @@ @color/colorAccent - + + -