android 15.0 Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标

1.概述

在15.0系统rom定制化开发手机项目中,在Launcher3中专门适配老年机的时候,这时客户提出要求,如果最后一屏未满时,不让拖拽到后面一屏的空屏中这样就需要获取当前是哪一屏,并且要知道当前有多少个Item,总共一屏最多多少个item

所以就需要从Workspace.java入手,来分析解决这个问题

2.Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心类

复制代码
    packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
    packages/apps/Launcher3/src/com/android/launcher3/CellLayout.java

3.Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心功能实现和分析

CellLayout:主屏幕中的每一页,其父布局就是Workspace,左右滑动屏幕,就是每一个CellLayout的变化过程,这个类中有很多处理拖拽相关方法

Workspace:就是CellLayout的父布局,所有的桌面app图标 hotseat图标 folder文件夹 widget小部件都是显示在workspace上的

Launcher顾名思义,就是桌面的意思,也是android系统启动后第一个启动的应用程序,

:Launcher3负责管理和展示用户手机桌面上的各个应用程序图标。它通过GridView或者LinearLayout等布局管理器将

图标进行排列,并支持滑动、放大缩小等手势操作

在实现Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心功能中,通过上述的分析得知,

Workspace就是CellLayout的父布局绑定这种图标的布局,

首选来看Workspace.java源码 开始拖拽时会调用startDrag()

和beginDragShared(View child, DragSource source, DragOptions options) 等

相关方法

复制代码
    public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) {
        View child = cellInfo.cell;
 
        mDragInfo = cellInfo;
        child.setVisibility(INVISIBLE);
 
        if (options.isAccessibleDrag) {
            mDragController.addDragListener(
                    new AccessibleDragListenerAdapter(this, WorkspaceAccessibilityHelper::new) {
                        @Override
                        protected void enableAccessibleDrag(boolean enable) {
                            super.enableAccessibleDrag(enable);
                            setEnableForLayout(mLauncher.getHotseat(), enable);
                        }
                    });
        }
 
        beginDragShared(child, this, options);
    }
         public void beginDragShared(View child, DragSource source, DragOptions options) {
        Object dragObject = child.getTag();
        if (!(dragObject instanceof ItemInfo)) {
            String msg = "Drag started with a view that has no tag set. This "
                    + "will cause a crash (issue 11627249) down the line. "
                    + "View: " + child + "  tag: " + child.getTag();
            throw new IllegalStateException(msg);
        }
        beginDragShared(child, null, source, (ItemInfo) dragObject,
                new DragPreviewProvider(child), options);
    }
 
          public DragView beginDragShared(View child, DraggableView draggableView, DragSource source,
                  ItemInfo dragObject, DragPreviewProvider previewProvider, DragOptions dragOptions) {
      
              float iconScale = 1f;
              if (child instanceof BubbleTextView) {
                  Drawable icon = ((BubbleTextView) child).getIcon();
                  if (icon instanceof FastBitmapDrawable) {
                      iconScale = ((FastBitmapDrawable) icon).getAnimatedScale();
                  }
              }
      
              // Clear the pressed state if necessary
              child.clearFocus();
              child.setPressed(false);
              if (child instanceof BubbleTextView) {
                  BubbleTextView icon = (BubbleTextView) child;
                  icon.clearPressedBackground();
              }
      
              mOutlineProvider = previewProvider;
      
              if (draggableView == null && child instanceof DraggableView) {
                  draggableView = (DraggableView) child;
              }
      
              final View contentView = previewProvider.getContentView();
              final float scale;
              // The draggable drawable follows the touch point around on the screen
              final Drawable drawable;
              if (contentView == null) {
                  drawable = previewProvider.createDrawable();
                  scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
              } else {
                  drawable = null;
                  scale = previewProvider.getScaleAndPosition(contentView, mTempXY);
              }
      
      .....
              return dv;
          }

在实现Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心功能中,通过上述的分析得知,在WorkSpace.java中,对手势拖拽icon的相关方法,从startDrag()beginDragShared() onDrap()等相关方法来处理拖拽的相关动作,

所以要首选看CellInfo这个内部类:

复制代码
  public static final class CellInfo extends CellAndSpan {
    public final View cell;
    final int screenId;
    public final int container;
    public CellInfo(View v, ItemInfo info) {
        cellX = info.cellX;
        cellY = info.cellY;
        spanX = info.spanX;
        spanY = info.spanY;
        cell = v;
        screenId = info.screenId;
        container = info.container;
    }
     
    @Override
    public String toString() {
        return "Cell[view=" + (cell == null ? "null" : cell.getClass())
                + ", x=" + cellX + ", y=" + cellY + "]";
    }
     
    }

在实现Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心功能中,通过上述的分析得知,

CellInfo这个内部类主要是记录每个Item的相关信息 属于哪一屏 x y坐标等

从源码中可以看出 刚好有screenId这个变量 就代表当前是哪一屏

继续看CellLayout.java源码

复制代码
   public int getCountX() {
    return mCountX;
    }
    public int getCountY() {
    return mCountY;
    }

发现getCountX代表有多少行 getCountY()有多少列

所以最多每一屏就是getCountX()*getCountY();

而当前屏有多少个Item

就是mShortcutsAndWidgets.getChildCount();

所以CellLayout.java增加个方法

public int childCount(){

if(mShortcutsAndWidgets==null)return 0;

return mShortcutsAndWidgets.getChildCount();

}

所以最终修改为:

复制代码
// add code start
    private int mCurScrrenId=-1,mCurChildCount=-1;
// add code end
 
     public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) {
        View child = cellInfo.cell;
 
        mDragInfo = cellInfo;
        child.setVisibility(INVISIBLE)
 
// add code start
    mCurScrrenId = cellInfo.screenId;
    CellLayout mSourceCellLayout = mWorkspaceScreens.valueAt(mCurScrrenId);
    mCurChildCount = mSourceCellLayout.childCount();
    if(mSourceCellLayout!=null)Log.e("Launcher3","source--countx:"+mSourceCellLayout.getCountX()+"--county:"+mSourceCellLayout.getCountY()+"---childcount:"+mCurChildCount+"mCurScrrenId:"+mCurScrrenId);
    // add code end
 
        if (options.isAccessibleDrag) {
            mDragController.addDragListener(
                    new AccessibleDragListenerAdapter(this, WorkspaceAccessibilityHelper::new) {
                        @Override
                        protected void enableAccessibleDrag(boolean enable) {
                            super.enableAccessibleDrag(enable);
                            setEnableForLayout(mLauncher.getHotseat(), enable);
                        }
                    });
        }
 
        beginDragShared(child, this, options);
    }

在实现Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心功能中,通过上述的分析得知,

在Workspace.java中的上述源码中,通过startDrag(CellLayout.CellInfo cellInfo, DragOptions options)的方法中

添加通过CellLayout中的mSourceCellLayout.childCount();计算当前各行各列的数据,来获取当前屏的count值

经过编译验证拖拽时当前屏和Item个数都是一样的

相关推荐
2501_944424121 小时前
Flutter for OpenHarmony游戏集合App实战之俄罗斯方块七种形状
android·开发语言·flutter·游戏·harmonyos
不会Android的潘潘3 小时前
受限系统环境下的 WebView 能力演进:车载平台 Web 渲染异常的根因分析与优化实践
android·java·前端·aosp
建军啊3 小时前
java web常见lou洞
android·java·前端
豆奶dudu3 小时前
安卓应用签名生成+微信开放平台安卓应用签名
android·微信开放平台
AC赳赳老秦5 小时前
Dify工作流+DeepSeek:运维自动化闭环(数据采集→报告生成)
android·大数据·运维·数据库·人工智能·golang·deepseek
2501_944424125 小时前
Flutter for OpenHarmony游戏集合App实战之记忆翻牌配对消除
android·java·开发语言·javascript·windows·flutter·游戏
2501_944526425 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 设置功能实现
android·javascript·flutter·游戏·harmonyos
冬奇Lab5 小时前
【Kotlin系列11】协程原理与实战(下):Flow与Channel驯服异步数据流
android·开发语言·kotlin
_昨日重现6 小时前
Jetpack系列之Compose Scaffold
android·android jetpack
2501_944424126 小时前
Flutter for OpenHarmony游戏集合App实战之数字拼图打乱排列
android·开发语言·flutter·游戏·harmonyos