最近遇到一个问题是布局使用了ScrollView+RecycleView,RecycleView中放了EditText,当进入页面的时候,
会自动定位到RecycleView的位置,需要手动向上滑动才能滚动到顶部,原因是RecycleView中的EditText自动获取到了焦点。
一开始的解决方案是直接在ScrollView包裹的第一个ViewGroup加上android:descendantFocusability="blocksDescendants"属性,该属性的作用是覆盖子类控件而直接获得焦点,android:descendantFocusability还有另外两个属性值beforeDescendants:viewgroup会优先其子类控件而获取到焦点afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点。
当使用上android:descendantFocusability="blocksDescendants"后,的确解决了自动滚动到RecycleView位置的问题,但是会出现RecycleView中的EditText点击无效的现象,究其原因是ViewGroup禁止了子控件获取焦点的原因,所以EditText获取不到了焦点。
新的解决方案是ViewGroup仍然加上android:descendantFocusability="blocksDescendants",给EditText加上触摸监听:
mEditText.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //通知ViewGroup修改android:descendantFocusability属性值 EventBus.getDefault().post(new EditTextTouchEvent()); return false; } });
上述代码的作用是当触摸到EditText时,在onTouch中通知ViewGroup修改android:descendantFocusability属性值,并返回false,不消耗触摸事件,触摸事件就能一直往下传,EditText就能收到点击事件。当页面收到EditTextTouchEvent事件时再动态修改ViewGroup的descendantFocusability的值,这样EditText就能获取焦点了,也就能点击有效了,如下:
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(EditTextTouchEvent event) { mViewGroup.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); }