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个数都是一样的

相关推荐
阿巴斯甜20 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker20 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952721 小时前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android