底层架构 数据算法 gitee mfc acm file yii path null onclick 百度seo关键词优化 vue的优点 vuejs视频教程 郑州网站开发 sql数据库教学视频 bootstrap侧边栏 kafka消费不到数据 js获取body的高度 plsql连接mysql python断言assert实例 python注释 python课程 python对象 python教程 python的开发工具 javatrim javaobject java中正则表达式 java的泛型 java集合类 javahttp windows7loader 简体中文语言包 易语言进度条 tftpd64 选项卡 3d软件下载 mysql使用教程 小程序开发工具下载 淘宝图片下载
当前位置: 首页 > 学习教程  > 编程语言

ViewPager2设置垂直显示导致页面内EditText焦点丢失

2020/10/8 18:17:20 文章标签:

新开了项目,在项目中使用到了vp2,记录印象最深刻的问题。 问题描述: 页面布局为顶部titlebar,左侧是RecycleView实现的一个菜单列表,右侧通过VP2来对Fragment进行管理。 当页面内容的长度超过屏幕的3/4时&#xff0c…

新开了项目,在项目中使用到了vp2,记录印象最深刻的问题。

问题描述:

页面布局为顶部titlebar,左侧是RecycleView实现的一个菜单列表,右侧通过VP2来对Fragment进行管理。

当页面内容的长度超过屏幕的3/4时,唤起软键盘会导致焦点丢失。再次点击后,输入一下后再次丢失焦点。

视频:https://v.qq.com/x/page/q3158tuiatf.html

前期解决思路:

通过设置edittext,强行获取焦点。


// 当前被选中的edittext的索引
int mCheckedEditIndex ;
// 使用map来存储所有的listener,在页面释放的时候取消监听,释放资源,防止内存泄漏
// 但是leakcanary仍旧会报内存泄漏,原因待查......
protected HashMap<View, ViewTreeObserver.OnGlobalLayoutListener> mViewOnLayoutListenerHashMap;

// 设置edittext的OnTouchListener, 给mCheckedEditIndex赋值
edittext.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mCheckedEditIndex = index;
                return false;
            }
        });

// 在给edittext设置布局变化的监听,如果当前的索引和自身的索引相同,则强制获取焦点,不是则放弃焦点
WeakReference<ItemEditBar> weakReference = new WeakReference<>(ieb);
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (weakReference.get() != null) {
                    if (mCheckedEditIndex == index) {
                        weakReference.get().getEtRoot().requestFocus();
                    } else {
                        weakReference.get().getEtRoot().clearFocus();
                    }
                }
            }
        };
ieb.getEtRoot().getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
mViewOnLayoutListenerHashMap.put(ieb, onGlobalLayoutListener);

这种思路可以解决焦点丢失的问题,但是会引入其他的问题,使用布局监听会导致内存泄漏,在较长的页面中,edittext无法取消获取焦点的动作,会导致页面滑动后 再次滑动到edittext所在位置。

再次研究后,查阅源码后发现可以设置全局的焦点变化的监听,后经过测试发现,在软键盘弹出的瞬间,焦点移动到了左侧的RecycleView的item上。结合log输出发现,此时vp2开始加载下一个页面的内容,故大胆猜测是因为vp2设置为垂直方向,在软键盘弹出时,页面重新绘制,VP2认为触发了向上的滑动操作(代码中已经设置不可滑动),VP2是使用RecycleView实现的,故滑动设置也是通过RecycleView来控制。

 private class RecyclerViewImpl extends RecyclerView {
        RecyclerViewImpl(@NonNull Context context) {
            super(context);
        }

       // ...

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            return isUserInputEnabled() && super.onInterceptTouchEvent(ev);
        }
    }

通过测试发现,当把Vp2设置成横向模式时,便不再产生焦点丢失问题。

反思

花了一天时间,终于解决这个问题,分享给大家,请勿踩坑。

对于VP2,其核心实现方式是RecycleView,在解决这个问题的时候发现自己对RecycleView源码的理解远远不够,仍需努力,加油~~

 

 

 


本文链接: http://www.dtmao.cc/news_show_250042.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?