From ded1a57f0c89c43fcda31c0804f7ac47851ed6c4 Mon Sep 17 00:00:00 2001 From: iPel Date: Wed, 22 Feb 2023 21:19:12 +0800 Subject: [PATCH] fix(android): textInput may throw IllegalStateException (#2957) * fix(android): textInput may throw IllegalStateException * fix(android): textInput may throw IllegalStateException --------- Co-authored-by: OpenHippy <124017524+open-hippy@users.noreply.github.com> --- .../views/hippylist/HippyRecyclerView.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java index ee99f4f33bb..71afca053f6 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java @@ -40,6 +40,7 @@ import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.IHeaderAttachListener; import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.IHeaderHost; import com.tencent.mtt.hippy.views.hippylist.recyclerview.helper.skikcy.StickyHeaderHelper; +import java.util.ArrayList; /** * Created on 2020/12/22. Description @@ -67,6 +68,7 @@ public class HippyRecyclerView extends Hip Priority.NOT_SET, Priority.NOT_SET, Priority.NOT_SET}; private int mNestedScrollAxesTouch; private int mNestedScrollAxesNonTouch; + private ArrayList mFocusableViews; public HippyRecyclerView(Context context) { super(context); @@ -553,7 +555,33 @@ public View focusSearch(View focused, int direction) { if (isTvPlatform) { return mFocusHelper.focusSearch(focused, direction); } - return super.focusSearch(focused, direction); + View result = super.focusSearch(focused, direction); + // {@link RecyclerView#focusSearch} may return not focusable view, + // cause IllegalStateException, so we verify again. + if (result == null || !verifyFocusable(result, direction)) { + return null; + } + return result; + } + + private boolean verifyFocusable(@NonNull View view, int direction) { + boolean inTouchMode = isInTouchMode(); + // first check whether self is able to take focus + if (inTouchMode ? view.isFocusableInTouchMode() : view.isFocusable()) { + return true; + } + // then check whether has focusable descendants + if (!(view instanceof ViewGroup)) { + return false; + } + if (mFocusableViews == null) { + mFocusableViews = new ArrayList<>(); + } + view.addFocusables(mFocusableViews, direction, inTouchMode ? FOCUSABLES_TOUCH_MODE : FOCUSABLES_ALL); + boolean result = !mFocusableViews.isEmpty(); + // clear up the temp array + mFocusableViews.clear(); + return result; } @Override