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

相关推荐
踏雪羽翼8 小时前
android TextView实现文字字符不同方向显示
android·自定义view·textview方向·文字方向·textview文字显示方向·文字旋转·textview文字旋转
lxysbly8 小时前
安卓玩MRP冒泡游戏:模拟器下载与使用方法
android·游戏
夏沫琅琊10 小时前
Android 各类日志全面解析(含特点、分析方法、实战案例)
android
程序员JerrySUN11 小时前
OP-TEE + YOLOv8:从“加密权重”到“内存中解密并推理”的完整实战记录
android·java·开发语言·redis·yolo·架构
TeleostNaCl12 小时前
Android | 启用 TextView 跑马灯效果的方法
android·经验分享·android runtime
TheNextByte113 小时前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn14 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪15 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥15 小时前
Android分层
android
极客小云17 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试