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

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

问题复现

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

小部件布局

正常情况点击事件传递

不能点击的情况

也会触发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();
+            }
        }
    }
相关推荐
studyForMokey19 分钟前
【Android面试】Gradle专题
android·面试·职场和发展
向上_503582912 小时前
配置Protobuf输出Java文件或kotlin文件
android·java·开发语言·kotlin
陆业聪2 小时前
AI 时代最被低估的工程师技能:把需求写清楚
android·人工智能·aigc
夏沫琅琊2 小时前
Android 的 Activity 启动模式
android
zh_xuan2 小时前
Android compose Navigation 页面导航
android·compose
luanma1509803 小时前
PHP vs C#:30字秒懂两大语言核心差异
android·开发语言·python·php·laravel
luanma1509804 小时前
Laravel 7.X核心特性深度解析
android·开发语言·php·lua·laravel
运维老曾4 小时前
Flink 1.20 使用自带jdbc source 操作步骤
android·adb·flink
陆业聪7 小时前
2026 年还在靠「感觉」调性能?Android Profiler 这样用才对
android·人工智能·性能优化
草莓熊Lotso7 小时前
MySQL 多表连接查询实战:内连接 + 外连接
android·运维·数据库·c++·mysql