【问题标题】:How to drag and drop while preserving the original android View?如何在保留原始android View的同时进行拖放?
【发布时间】:2014-12-09 23:09:53
【问题描述】:

我正在开发一款 Android 游戏。

我想知道拖放是否只是解决此问题的错误方法。我正在寻找的效果是有一个按钮,当用户长按时,将启动一个拖放效果,以投影为目标。

此自定义拖动阴影将持续存在,直到用户释放目标阴影。我有自定义阴影工作并且正在响应拖动事件。我不确定的是如何在不实际移动它们开始拖动的按钮的情况下使整个工作正常工作。

是否像不将原始视图(按钮)传递给阴影生成器一样简单?

编辑


添加了我用来启动拖动的触摸监听器的定义。

private final class MyTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
      if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
        ClipData data = ClipData.newPlainText("", "");
        //DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
        view.startDrag(data, new TargetDragShadowBuilder(view), view, 0);
        view.setVisibility(View.INVISIBLE);
        return true;
      } else {
        return false;
      }
    }
  }

我在此处设置可见性,但坦率地说,我正在尝试按照此处的教程进行操作:
http://www.vogella.com/tutorials/AndroidDragAndDrop/article.html

也许这是错误的方法。我基本上希望执行以下步骤:

1) 检测以按钮开始的拖动事件

2) 在不以任何方式更改按钮的情况下,我希望我指定的图片的自定义投影(具有透明度)在用户拖过屏幕时出现在用户手指下方。

最终我需要弄清楚如何使阴影闪烁,或在消失前徘徊几秒钟,并获得用户松开手指的位置。看起来从文档中我可以从 ACTION_DRAG_LOCATION...?

【问题讨论】:

  • 什么是“目标”,你想移动谁的影子?
  • 我不太明白这个问题...在Android中,拖动操作只会“移动”DragShadowBuilder构造的阴影,原始视图不会改变(除非你正在这样做明确)。究竟是什么问题?如果需要,您可以使用 DragShadowBuilder 的自定义实现来提供完全不同的影子。
  • 让我理解一下:你想拖动一个下方有阴影的按钮,当你离开它时,按钮又回到它的初始位置?在它发布的那一刻你会怎么做?
  • 我有一个按钮。我想允许用户将手指从该按钮拖到视图的其他位置。现在按钮正在用他们的手指移动。我的自定义阴影是一个大红色圆圈。一旦用户松开手指,圆圈和按钮就消失了。我想要的行为是按钮完全不受影响,当用户拖动手指时红色圆圈出现,松开时消失。

标签: android android-layout drag-and-drop android-view


【解决方案1】:

有一个官方API Guide关于如何在Android中实现拖放。不幸的是,bonnyz 提出的解决方案不符合本指南 - 添加临时视图以指示拖动操作在某种程度上是一种重量级的解决方案。

回答你的问题:

是否像不将原始视图(按钮)传递给阴影生成器一样简单?

文档说:

View.DragShadowBuilder(视图)

此构造函数接受您应用程序的任何 View 对象。构造函数将 View 对象存储在 View.DragShadowBuilder 对象中,因此在回调期间您可以在构造拖动阴影时访问它。它不必与用户选择开始拖动操作的视图(如果有)相关联。

因此,您通过那里的视图不用于表示阴影。阴影是您在 onDrawShadow() 方法实现中在 Canvas 上绘制的内容。

基本上,阴影只是一个图形,在手指被放下时跟随手指。它不是视图,并且不必看起来像活动中的任何视图。它是任意图形,可让用户了解拖放的内容。

【讨论】:

  • 对,但我的问题是视图(原始按钮)在被拖动时实际上正在消失。我正在尝试在不影响原始视图(按钮)的同时创建自定义阴影。我开始怀疑答案是否以某种方式不使按钮具有拖放侦听器,但仍支持拖放阴影效果。这似乎不应该是那么罕见的场景
  • 被拖动的按钮不应注册setOnDragListener()。您只需为视图设置拖动侦听器以接收拖放。但是,在我的实验中,我无法重现您的问题 - 可拖动视图永远不会消失。你会在某处改变它的可见性吗?
  • 为我正在使用的触摸侦听器添加了描述,是的,它正在设置视图可见性......有些东西告诉我我做错了......
  • 问题是我将视图设置为不可见(facepalm)以响应触摸侦听器。此外,我的影子正在将视图传递给 super(),从而使视图随之而来。综合效果是视图的外观被拖走并永远丢失。通过删除可见性调用并从客户 dropshadowbuilder 中的超类中删除视图来修复。
【解决方案2】:

这是我的建议:

1)当用户长按按钮时,获取按钮的绝对坐标

 int coord[] = new int[2];
 button.getLocationOnScreen(coord);

2) 创建“ShadowView”,当用户拖动时需要在手指下显示(如您所愿)

3)ShadowView 附加到 Window(不改变其他布局):

windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

View shadowView = /..shadow view.../

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_PHONE,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT);

params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = coord[0]; //add offset if needed 
params.y = coord[1];

windowManager.addView(shadowView, params);

4) 使用用户拖动位置更新params

params.x = // drag X - halfsize of the view's width
params.y = // drag Y - halfsize of the view's height
windowManager.updateViewLayout(shadowView, params);

5)当用户停止拖动时,从Window中移除ShadowView

windowManager.removeViewImmediate(shadowView);

【讨论】:

  • 谢谢。我将对此进行试验,并让你知道它是如何进行的。如果它看起来有意义/有效,我会接受并关闭。
  • 从调查来看,这似乎是一种非常严厉的方法,用于创建和销毁不符合 Android 拖放规范的视图。我不确定这是因为我的问题是在推动非典型场景,还是因为疏忽。感谢您的回复,我当然不会投反对票,但我也不能奖励赏金。再次感谢。
【解决方案3】:

问题是我将视图设置为不可见(facepalm)以响应触摸侦听器。此外,我的影子正在将视图传递给 super(),从而使视图随之而来。综合效果是视图的外观被拖走并永远丢失。通过删除可见性调用并从客户 dropshadowbuilder 中的超类中删除视图来修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多