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

相关推荐
某空m3 分钟前
【Android】浅析DataBinding
android·开发语言
sky北城1 小时前
You are not able to choose some of the languages, because locales for them a
android
儿歌八万首1 小时前
Jetpack Compose 实战:打造高性能轮播图 (Carousel) 组件
android·前端·kotlin
QING6181 小时前
Kotlin Flow 防抖(Debounce)详解
android·kotlin·android jetpack
QING6181 小时前
Kotlin Flow 防抖(Debounce)、节流(Throttle)、去重(distinctUntilChanged) —— 新手指南
android·kotlin·android jetpack
AI视觉网奇2 小时前
android yolo12 android 实战笔记
android·笔记·yolo
海上飞猪2 小时前
【Mysql】Mysql的安装部署和使用
android·mysql·adb
我是好小孩2 小时前
【Android】项目的组件化搭建
android
aqi003 小时前
FFmpeg开发笔记(九十四)基于Kotlin的国产开源推拉流框架anyRTC
android·ffmpeg·kotlin·音视频·直播·流媒体
马 孔 多 在下雨3 小时前
Android 组件化开发基础实践
android