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

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

问题复现

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

小部件布局

正常情况点击事件传递

不能点击的情况

也会触发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();
+            }
        }
    }
相关推荐
百锦再8 小时前
React编程高级主题:测试代码
android·前端·javascript·react.js·前端框架·reactjs
2501_916008899 小时前
全面介绍Fiddler、Wireshark、HttpWatch、SmartSniff和firebug抓包工具功能与使用
android·ios·小程序·https·uni-app·iphone·webview
玉梅小洋9 小时前
Windows 10 Android 构建配置指南
android·windows
Libraeking11 小时前
视觉篇:Canvas 自定义绘图与高级动画的华丽圆舞曲
android·经验分享·android jetpack
Fushize12 小时前
多模块架构下的依赖治理:如何避免 Gradle 依赖地狱
android·架构·kotlin
Jomurphys12 小时前
Kotlin - 类型别名 typealias
android·kotlin
Haha_bj12 小时前
Flutter ——flutter_screenutil 屏幕适配
android·ios
Haha_bj13 小时前
Flutter ——device_info_plus详解
android·flutter·ios
前端小伙计13 小时前
Android/Flutter 项目统一构建配置最佳实践
android·flutter
Mr_sun.14 小时前
Day09——入退管理-入住-2
android·java·开发语言