当前位置: 首页 > news >正文

【安卓13】谷歌原生桌面launcher3 禁止桌面图标拖拽和所有应用拖拽

前言

如果我们需要固定住布局,不给用户拖拽,可以通过修改长按点击监听事件来达到禁止拖拽的目的

二、代码追踪

1、src/com/android/launcher3/touch/ItemLongClickListener.java
在这个类开头注册了两种类型的监听,一个是在桌面拖拽应用,一个是在所有应用里面长按拖拽

/*** Class to handle long-clicks on workspace items and start drag as a result.*/
public class ItemLongClickListener {public static final OnLongClickListener INSTANCE_WORKSPACE =ItemLongClickListener::onWorkspaceItemLongClick;public static final OnLongClickListener INSTANCE_ALL_APPS =ItemLongClickListener::onAllAppsItemLongClick;

接着分析桌面的长按事件

    private static boolean onWorkspaceItemLongClick(View v) {if (v instanceof LauncherAppWidgetHostView) {TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Widgets.onLongClick");} else {TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onWorkspaceItemLongClick");}Launcher launcher = Launcher.getLauncher(v.getContext());if (!canStartDrag(launcher)) return false;//请注意这里,这里判断是否允许拖拽,如果不允许拖拽,则用户长按的时候是没有任何反应的,包括长按卸载和快捷方式啥的都没有了。所以不可以在这里修改if (!launcher.isInState(NORMAL) && !launcher.isInState(OVERVIEW)) return false;if (!(v.getTag() instanceof ItemInfo)) return false;launcher.setWaitingForResult(null);beginDrag(v, launcher, (ItemInfo) v.getTag(), launcher.getDefaultWorkspaceDragOptions());return true;}

我们看到有**beginDrag(v, launcher, (ItemInfo) v.getTag(), launcher.getDefaultWorkspaceDragOptions());**这个方法,这个方法也是不能注释掉的,点进去这个方法

    public static void beginDrag(View v, Launcher launcher, ItemInfo info,DragOptions dragOptions) {if (info.container >= 0) {Folder folder = Folder.getOpen(launcher);if (folder != null) {if (!folder.getIconsInReadingOrder().contains(v)) {folder.close(true);} else {folder.startDrag(v, dragOptions);return;}}}CellLayout.CellInfo longClickCellInfo = new CellLayout.CellInfo(v, info);launcher.getWorkspace().startDrag(longClickCellInfo, dragOptions);}

重点关注最后一行,发现走到了我们的主桌面workspace,点进去继续看

    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);}

还是最后一行代码,点进去才到重点

    /*** Core functionality for beginning a drag operation for an item that will be dropped within* the workspace*/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();}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);}int halfPadding = previewProvider.previewPadding / 2;int dragLayerX = mTempXY[0];int dragLayerY = mTempXY[1];Point dragVisualizeOffset = null;Rect dragRect = new Rect();if (draggableView != null) {draggableView.getSourceVisualDragBounds(dragRect);dragLayerY += dragRect.top;dragVisualizeOffset = new Point(- halfPadding, halfPadding);}if (child.getParent() instanceof ShortcutAndWidgetContainer) {mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent();}if (child instanceof BubbleTextView) {BubbleTextView btv = (BubbleTextView) child;if (!dragOptions.isAccessibleDrag) {dragOptions.preDragCondition = btv.startLongPressAction();}if (btv.isDisplaySearchResult()) {dragOptions.preDragEndScale = (float) mAllAppsIconSize / btv.getIconSize();}}final DragView dv;//start change that do not to drop the workspace and allApps icon./*if (contentView instanceof View) {if (contentView instanceof LauncherAppWidgetHostView) {mDragController.addDragListener(new AppWidgetHostViewDragListener(mLauncher));}dv = mDragController.startDrag(contentView,draggableView,dragLayerX,dragLayerY,source,dragObject,dragVisualizeOffset,dragRect,scale * iconScale,scale,dragOptions);} else {dv = mDragController.startDrag(drawable,draggableView,dragLayerX,dragLayerY,source,dragObject,dragVisualizeOffset,dragRect,scale * iconScale,scale,dragOptions);}return dv;*///end change that do not to drop the workspace and allApps icon.return null;}

这个方法是拖拽的核心方法,在开始拖拽之前执行,改方法前面都是一些计算,不用看,重点看final DragView dv;后面这个if语句,这里构造一个拖拽对象,我们将该对象构造过程给注释掉,返回一个null,这样子,后续的所有拖拽流程都无法进行了,因为没有拖拽对象了,这样子我们就把禁止拖拽禁掉了,同时长按桌面添加微件的功能还是正常的,不影响其他长按功能。
因为所有应用里面的拖拽最终也是走到了最后一个方法,所以所有应用的拖拽也被禁掉了

相关文章:

  • 怎么去掉邮件内容中的回车符
  • 【JavaEE】Servlet API 详解(HttpServletRequest类)
  • Java进阶API第三章
  • 用人话讲解深度学习中CUDA,cudatookit,cudnn和pytorch的关系
  • 叙永微公益:开展“活水计划-益童成长守护”周末陪伴活动
  • [EFI]Lenovo ThinkPad X280电脑 Hackintosh 黑苹果引导文件
  • 设计基于STM32F103C8T6微控制器的巡线小车
  • Angular 由一个bug说起之二:trackBy的一点注意事项
  • excel导入 Easy Excel
  • idea一键打包docker镜像并推送远程harbor仓库的方法(包含spotify和fabric8两种方法)--全网唯一正确,秒杀99%水文
  • 前台页面从数据库中获取下拉框值
  • (SpringBoot)第七章:SpringBoot日志文件
  • 15分钟,不,用模板做数据可视化只需5分钟
  • Django模板层
  • GAT里面的sofamax函数的实现:
  • [NodeJS] 关于Buffer
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 2017年终总结、随想
  • dva中组件的懒加载
  • flutter的key在widget list的作用以及必要性
  • HashMap剖析之内部结构
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • LeetCode算法系列_0891_子序列宽度之和
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • 构造函数(constructor)与原型链(prototype)关系
  • 前端设计模式
  • 悄悄地说一个bug
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • kubernetes资源对象--ingress
  • scrapy中间件源码分析及常用中间件大全
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $(selector).each()和$.each()的区别
  • (C#)一个最简单的链表类
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)Linq学习笔记
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .Net 8.0 新的变化
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .NET中GET与SET的用法
  • .skip() 和 .only() 的使用
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项
  • [ARC066F]Contest with Drinks Hard
  • [bzoj1912]异象石(set)