桌面列表小部件不能点击的问题分析

桌面列表小部件不能点击的问题分析

问题复现

拖动谷歌浏览器的小部件到桌面,"打开新的标签页"不能点击,没有按压效果

小部件布局

正常情况点击事件传递

不能点击的情况

也会触发AbsListView.onTounchDown和AbsListView.onTouchUP,但没有按压效果和点击事件触发

分析:

拖动小部件放到桌面时会触发AbsListView的onAttachedToWindow,mDataChanged被赋值为true frameworks/base/core/java/android/widget/AbsListView.java

js 复制代码
    protected void onAttachedToWindow() {
        if (mAdapter != null && mDataSetObserver == null) {
...
            mDataChanged = true;
        }
    }

mDataChanged = true,列表的点击事件PerformClick.run无法处理 frameworks/base/core/java/android/widget/AbsListView.java

js 复制代码
    private void onTouchUp(MotionEvent ev) {
        switch (mTouchMode) {
            case TOUCH_MODE_DOWN:
            case TOUCH_MODE_TAP:
            case TOUCH_MODE_DONE_WAITING:
...
                        if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
...
                            if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
...
                                layoutChildren();
                                child.setPressed(true);
...
                                setPressed(true);
...
                                mTouchModeReset = new Runnable() {
                                    @Override
                                    public void run() {
                                        mTouchModeReset = null;
                                        mTouchMode = TOUCH_MODE_REST;
                                        child.setPressed(false);
                                        setPressed(false);
                                        if (!mDataChanged && !mIsDetaching
                                                && isAttachedToWindow()) {
                                            performClick.run();
                                        }
                                    }
                                };
                                postDelayed(mTouchModeReset,
                                        ViewConfiguration.getPressedStateDuration());
..
                    }
                }

安卓15无此问题:

触摸一下就会触发DOWN,MOVE,MOVE,UP 对比Android14机器

只触发DOWN,UP

因此Android 15会在点击时多处理move事件

move事件处理中mDataChanged为true时,会调用layoutChildren(),此函数中可以将mDataChanged重新置为false,onTouchUp就可以正常触发点击事件 frameworks/base/core/java/android/widget/AbsListView.java

js 复制代码
    private void onTouchMove(MotionEvent ev, MotionEvent vtev) {
...
        if (mDataChanged) {
            layoutChildren();
        }

frameworks/base/core/java/android/widget/ListView.java

js 复制代码
    protected void layoutChildren() {
...
            mLayoutMode = LAYOUT_NORMAL;
            mDataChanged = false;
...
    }

解决

此问题为AOSP的原生bug,在onAttachedToWindow后重新请求布局更新 frameworks/base/core/java/android/widget/AbsListView.java

js 复制代码
    protected void onAttachedToWindow() {
....
        if (mAdapter != null && mDataSetObserver == null) {
.....
            mDataChanged = true;
...
+            if (mAdapter instanceof RemoteViewsAdapter) {
+                requestLayout();
+            }
        }
    }
相关推荐
阿pin3 小时前
Android随笔-kotlin withContext
android·kotlin·withcontext
树码小子4 小时前
开启 IDEA 中的断言功能
android·java·intellij-idea
Android-Flutter5 小时前
android 动画详解
android·kotlin
小孔龙10 小时前
GraphicBuffer 跨进程共享
android
行业研究员11 小时前
Android内置GPS与腾讯地图定位技术对比分析
android·android定位·腾讯地图定位
Android-Flutter11 小时前
android WMS 详解(二)
android·kotlin
游戏开发爱好者812 小时前
App Store 上传 IPA 自动化,.p8 密钥认证与 CI/CD 接入实战
android·运维·ci/cd·小程序·uni-app·自动化·iphone
游戏开发爱好者813 小时前
iOS 推送怎么配置,APNs 推送证书、设备库与群发
android·ios·小程序·https·uni-app·iphone·webview
阿pin14 小时前
Android随笔-kotlin 高阶函数
android·kotlin·高阶函数
wxson72821 天前
【Android视频监控系统技术总结】
android·音视频