拖动视图时设置自定义锚点
Posted
技术标签:
【中文标题】拖动视图时设置自定义锚点【英文标题】:Set custom anchor when dragging a View 【发布时间】:2014-04-22 21:22:54 【问题描述】:我正在使用 android Drag&Drop API 并尝试将拖动阴影的锚点设置为在 View
中进行触摸的点。默认行为是将锚点放在View
的中间。
我做了一些研究,似乎这可以通过覆盖DragShadowBuilder
类中的onProvideShadowMetrics (Point shadowSize, Point shadowTouchPoint)
方法来完成。据我了解,如果我更改 shadowTouchPoint
的 x,y 坐标,它应该会修改拖动锚点的坐标。
我所做的是像这样扩展DragShadowBuilder
类:
class EventDragShadowBuilder extends DragShadowBuilder
int touchPointXCoord, touchPointYCoord;
public EventDragShadowBuilder()
super();
public EventDragShadowBuilder(View view, int touchPointXCoord,
int touchPointYCoord)
super(view);
this.touchPointXCoord = touchPointXCoord;
this.touchPointYCoord = touchPointYCoord;
@Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint)
shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
在我使用拖放的Fragment
中,我创建了两个侦听器来为View
启动拖动事件:
mEventLongClickListener = new OnLongClickListener()
@Override
public boolean onLongClick(View view)
EventDragShadowBuilder shadowBuilder = new EventDragShadowBuilder(
view, mEventTouchXCoord, mEventTouchYCoord);
view.startDrag(null, shadowBuilder, view, 0);
return true;
;
// We need this listener in order to get the corect coordinates for the
// drag shadow
mEventTouchListener = new OnTouchListener()
@Override
public boolean onTouch(View view, MotionEvent event)
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK)
case MotionEvent.ACTION_DOWN:
mEventTouchXCoord = (int) event.getX();
mEventTouchYCoord = (int) event.getY();
break;
return false;
;
我设置了两个监听器:
itemView.setOnLongClickListener(mEventLongClickListener);
itemView.setOnTouchListener(mEventTouchListener);
到这里为止一切正常。但是当我测试应用程序并开始拖动过程时,拖动阴影在触摸点下方居中。所以它使用默认行为。我尝试调试,发现mEventTouchXCoord
和mEventTouchYCoord
设置正确。 shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
方法获得了正确的坐标,但它仍然使阴影居中。
我不知道我做错了什么。也许我误解了 API。任何帮助或提示将不胜感激。
【问题讨论】:
【参考方案1】:好的,就像 Scoup 所说的,问题出在 onProvideShadowMetrics()
方法中。事实是,如果我删除超级构造函数super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
,它就不会再显示拖动阴影了。
仔细研究一下我发现的 API 方法:
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
final View view = mView.get();
if (view != null)
shadowSize.set(view.getWidth(), view.getHeight());
shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
else
Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
确实,它会将shadowTouchPoint
重置到被拖动的View
的中间。但它也将拖动阴影初始化为正确的尺寸。虽然我希望正确设置拖动阴影尺寸,但我不想重置 shadowTouchPoint
。
实现这一点的最简单方法是调用超级构造函数在使用自定义值初始化shadowTouchPoint
,如下所示:
@Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint)
super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
另一种解决方案是自己处理拖动阴影View
,完全跳过超级构造函数。我会回来提供详细的更新。
【讨论】:
【参考方案2】:我猜问题出在这行super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
您已经在shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
中更改了shadowTouchPoint 的值,但是当调用super 时,您传递的shadowTouchPoint 被替换为“super”默认方法,并且默认行为是shadowTouchPoint 居中。
所以,只需删除这一行。
【讨论】:
感谢您的回答。它没有解决我的问题,但你让我走上了正确的道路。为此 +1 经过一番考虑,我决定给你赏金,因为你的回答确实帮助我解决了这个问题:) 谢谢。我很高兴能提供帮助!以上是关于拖动视图时设置自定义锚点的主要内容,如果未能解决你的问题,请参考以下文章
使用 Web 服务保存共享点自定义 Web 部件时格式正确的 XML 错误