我正在使用Android Drag& Drop API,并尝试将拖动阴影的锚点设置为View
中触摸点的位置。 dafault行为是将锚点放在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。任何帮助或暗示都将非常感激。
答案 0 :(得分:11)
好的,就像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
并完全跳过超级构造函数。我会回来详细更新。
答案 1 :(得分:8)
我想问题是这一行super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
你已经在shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
中更改了shadowTouchPoint的值,但是当调用super时,你传递的是由" super"替换的shadowTouchPoint。默认方法,默认行为是shadowTouchPoint的中心。
所以,只需删除此行。