android 15.0 Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标
1.概述
在15.0系统rom定制化开发手机项目中,在Launcher3中专门适配老年机的时候,这时客户提出要求,如果最后一屏未满时,不让拖拽到后面一屏的空屏中这样就需要获取当前是哪一屏,并且要知道当前有多少个Item,总共一屏最多多少个item
所以就需要从Workspace.java入手,来分析解决这个问题
2.Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标的核心类
packages/apps/Launcher3/src/com/android/launcher3/Workspace.javapackages/apps/Launcher3/src/com/android/launcher3/CellLayout.java3.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) {@Overrideprotected 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 necessarychild.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 screenfinal 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;}@Overridepublic 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 startprivate int mCurScrrenId=-1,mCurChildCount=-1;
// add code endpublic void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) {View child = cellInfo.cell;mDragInfo = cellInfo;child.setVisibility(INVISIBLE)// add code startmCurScrrenId = 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 endif (options.isAccessibleDrag) {mDragController.addDragListener(new AccessibleDragListenerAdapter(this, WorkspaceAccessibilityHelper::new) {@Overrideprotected 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个数都是一样的
