From e2417b31a16d83e9ef9225bab7bbb1d463a20602 Mon Sep 17 00:00:00 2001 From: cgspine Date: Tue, 26 Apr 2022 17:32:00 +0800 Subject: [PATCH] bugfix: requestLayout invoked frequently. --- .../com/qmuiteam/qmui/arch/QMUIActivity.java | 10 ++++++ .../com/qmuiteam/qmui/arch/QMUIFragment.java | 9 ++++++ .../qmuiteam/qmui/arch/SwipeBackLayout.java | 32 +++++++++++++++++++ ...MUIContinuousNestedBottomRecyclerView.java | 12 ++++--- .../QMUIContinuousNestedTopRecyclerView.java | 12 ++++--- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java index 870eef36..39530558 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java @@ -29,6 +29,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.WindowInsetsCompat; +import com.qmuiteam.qmui.QMUILog; import com.qmuiteam.qmui.arch.scheme.ActivitySchemeRefreshable; import com.qmuiteam.qmui.util.QMUIDisplayHelper; import com.qmuiteam.qmui.util.QMUIStatusBarHelper; @@ -127,6 +128,11 @@ public class QMUIActivity extends InnerBaseActivity implements ActivitySchemeRef return QMUIActivity.this.getDragDirection(swipeBackLayout,moveAction,downX, downY, dx, dy, touchSlop); } + + @Override + public void reportFrequentlyRequestLayout(int count, long duration) { + QMUIActivity.this.reportFrequentlyRequestLayout(count, duration); + } }; @Override @@ -200,6 +206,10 @@ public class QMUIActivity extends InnerBaseActivity implements ActivitySchemeRef super.onBackPressed(); } + protected void reportFrequentlyRequestLayout(int count, long duration){ + QMUILog.w(TAG, "requestLayout is too frequent(requestLayout " + count + "times within " + duration + "ms"); + } + public boolean isInSwipeBack() { return mIsInSwipeBack; } diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java index b7606b4a..1af19c75 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java @@ -597,6 +597,11 @@ public abstract class QMUIFragment extends Fragment implements return QMUIFragment.this.getDragDirection( swipeBackLayout, viewMoveAction, downX, downY, dx, dy, touchSlop); } + + @Override + public void reportFrequentlyRequestLayout(int count, long duration) { + QMUIFragment.this.reportFrequentlyRequestLayout(count, duration); + } }); initSwipeBackLayout(swipeBackLayout); if(getParentFragment() != null){ @@ -1011,6 +1016,10 @@ public abstract class QMUIFragment extends Fragment implements onNormalBackPressed(); } + protected void reportFrequentlyRequestLayout(int count, long duration){ + QMUILog.w(TAG, "requestLayout is too frequent(requestLayout " + count + "times within " + duration + "ms"); + } + protected void onHandleSpecLastFragmentFinish(FragmentActivity fragmentActivity, QMUIFragment.TransitionConfig transitionConfig, Object toExec) { diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java b/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java index d06805b3..c7d35dcd 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; +import android.os.SystemClock; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -115,6 +116,9 @@ public class SwipeBackLayout extends FrameLayout { private boolean mIsScrollOverValid = true; private boolean mEnableSwipeBack = true; + private int mRequestLayoutCount = 0; + private long mRequestLayoutCheckStartTime = -1; + public SwipeBackLayout(Context context) { this(context, null); @@ -338,6 +342,32 @@ public class SwipeBackLayout extends FrameLayout { } } + @Override + public void requestLayout() { + super.requestLayout(); + mRequestLayoutCount++; + if(mRequestLayoutCheckStartTime == -1){ + mRequestLayoutCheckStartTime = SystemClock.elapsedRealtime(); + } + if(mRequestLayoutCount >= 100){ + long duration = SystemClock.elapsedRealtime() - mRequestLayoutCheckStartTime; + if(duration < 4000){ + if(mCallback != null){ + mCallback.reportFrequentlyRequestLayout(mRequestLayoutCount, duration); + } + } + mRequestLayoutCount = 0; + mRequestLayoutCheckStartTime = -1; + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mRequestLayoutCount=0; + mRequestLayoutCheckStartTime = -1; + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(!mEnableSwipeBack){ @@ -861,6 +891,8 @@ public class SwipeBackLayout extends FrameLayout { public interface Callback { int getDragDirection(SwipeBackLayout swipeBackLayout, ViewMoveAction moveAction, float downX, float downY, float dx, float dy, float touchSlop); + + void reportFrequentlyRequestLayout(int count, long duration); } public interface ViewMoveAction { diff --git a/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedBottomRecyclerView.java b/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedBottomRecyclerView.java index d0e29f32..430566c1 100644 --- a/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedBottomRecyclerView.java +++ b/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedBottomRecyclerView.java @@ -85,11 +85,15 @@ public class QMUIContinuousNestedBottomRecyclerView extends RecyclerView @Override public void consumeScroll(int yUnconsumed) { if (yUnconsumed == Integer.MIN_VALUE) { - scrollToPosition(0); + if(canScrollVertically(-1)){ + scrollToPosition(0); + } } else if (yUnconsumed == Integer.MAX_VALUE) { - Adapter adapter = getAdapter(); - if (adapter != null) { - scrollToPosition(adapter.getItemCount() - 1); + if(canScrollVertically(1)) { + Adapter adapter = getAdapter(); + if (adapter != null) { + scrollToPosition(adapter.getItemCount() - 1); + } } } else { boolean reStartNestedScroll = false; diff --git a/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedTopRecyclerView.java b/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedTopRecyclerView.java index b77d13c0..b7655381 100644 --- a/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedTopRecyclerView.java +++ b/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedTopRecyclerView.java @@ -56,12 +56,16 @@ public class QMUIContinuousNestedTopRecyclerView extends RecyclerView implements @Override public int consumeScroll(int dyUnconsumed) { if (dyUnconsumed == Integer.MIN_VALUE) { - scrollToPosition(0); + if(canScrollVertically(-1)){ + scrollToPosition(0); + } return Integer.MIN_VALUE; } else if (dyUnconsumed == Integer.MAX_VALUE) { - Adapter adapter = getAdapter(); - if (adapter != null) { - scrollToPosition(adapter.getItemCount() - 1); + if(canScrollVertically(1)){ + Adapter adapter = getAdapter(); + if (adapter != null) { + scrollToPosition(adapter.getItemCount() - 1); + } } return Integer.MAX_VALUE; }