gpt4 book ai didi

Android:将项目拖出滚动列表/画廊

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:39 26 4
gpt4 key购买 nike

我想实现一个允许用户将项目拖出的画廊。这不应该妨碍滚动/滑动。

鉴于界面布局,用户只能沿垂直路径将项目拖出图库,并水平滚动图库。

这可行吗?有没有一种简单的方法来检测水平运动,将它们推迟到画廊的事件处理程序,并拦截垂直运动?还是我必须重写 onInterceptTouchEvent() 并自己计算?

(编辑:我尝试使用 GestureListener,覆盖 onFling 和 onScroll,并在垂直滚动距离低于阈值时将事件传递给画廊)

最佳答案

我继承了Gallery,覆盖了onScroll方法。我还没有实现拖放逻辑,但是拖动和滚动工作。

当我有空的时候,我会在我的博客中写一篇完整的文章,详细介绍掉落机制。现在,一个简单的复制粘贴,以防将来有人访问此页面。

为了保持行为在其所属的位置,我创建了这个 DraggableView 接口(interface):

public interface DraggableView {
public void beforeDrag();

public DragView createDragView();
public Object getDraggedInfo();

public void afterDrop();
}

图库中的 View 如果实现了此 View ,则可以拖出图库区域。他们在前后都会收到通知,并且必须实现两个方法:

  • createDragView() 返回一个 DragView 对象。基本上,一个透明的悬停位图伴随着用户的移动。

  • getDraggedInfo() 返回应该到达放置目标的信息。

这是 DragView 类:

public class DragView extends ImageView {

private final LayoutParams mLayoutParams;

public DragView(Context context, Bitmap bitmap) {
super(context);

mLayoutParams = new LayoutParams();

mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;

mLayoutParams.height = LayoutParams.WRAP_CONTENT;
mLayoutParams.width = LayoutParams.WRAP_CONTENT;

mLayoutParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE
| LayoutParams.FLAG_NOT_TOUCHABLE;

mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.windowAnimations = 0;

mLayoutParams.alpha = 0.5f;

setImageBitmap(bitmap);

setLayoutParams(mLayoutParams);
}

public void move(int x, int y) {
mLayoutParams.x = x;
mLayoutParams.y = y;
}
}

如您所见,它在构造中采用了一个Bitmap,并创建了一个悬停的ImageView。最后,这是实现这一切的画廊代码(刚刚实现但不是很干净):

public class DraggableItemGallery extends Gallery {

private boolean mDragging;
private DragView mDragView;
private DraggableView mDragViewOwner;

private WindowManager mWindowManager;

private boolean mScrollStarted;

public DraggableItemGallery(Context context) {
super(context);
initialize();
}

public DraggableItemGallery(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}

public DraggableItemGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}

public void initialize() {
mWindowManager = (WindowManager)
getContext().getSystemService("window");
}

private void startDraggingItem(DraggableView view, int x, int y) {
mDragging = true;
mDragViewOwner = view;
mDragView = view.createDragView();

mDragView.move(x, y);

mWindowManager.addView(mDragView, mDragView.getLayoutParams());
}

private void continueDraggingItem(int x, int y) {
DragView dragView = getDragView();

dragView.move(x, y);
mWindowManager.updateViewLayout(dragView, dragView.getLayoutParams());
}

private void stopDraggingItem() {
mDragging = false;

mWindowManager.removeView(mDragView);

mDragViewOwner.afterDrop();

mDragView = null;
mDragViewOwner = null;
}

private DraggableView getDraggedItem() {
return mDragViewOwner;
}

private DragView getDragView() {
return mDragView;
}

private boolean isDraggingItem() {
return (mDragging);
}

private void setScrolling(boolean scrolling) {
mScrollStarted = scrolling;
System.out.println("Scrolling " + scrolling);
}

private boolean isScrolling() {
return mScrollStarted;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

if ((event.getAction() & ACTION_MASK) == ACTION_UP) {
setScrolling(false);

if (isDraggingItem())
stopDraggingItem();
}

return super.onTouchEvent(event);
}


final Rect onScroll_tempRect = new Rect();

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (isScrolling()) {
if (isDraggingItem()) {
int x = (int) e2.getX(),
y = (int) e2.getY();

System.out.println("Moving to " + x + " " + y);

continueDraggingItem(x, y);
return true;

} else {
/* Not dragging, let the Gallery handle the event */
return super.onScroll(e1, e2, distanceX, distanceY);
}

} else {
setScrolling(true);
boolean isVertical = (Math.abs(distanceY) > Math.abs(distanceX));

if (isVertical) {
int x = (int) e1.getX(),
y = (int) e1.getY();

View hitChild = null;

// A tiny optimization, declared above this method
final Rect hitRect = onScroll_tempRect;

for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.getHitRect(hitRect);

if (hitRect.contains(x, y)) {
hitChild = child;
break;
}
}

if (hitChild instanceof DraggableView) {
startDraggingItem((DraggableView) hitChild, x, y);
return true;
}
}

/* Either the scroll is not vertical, or the point
* of origin is not above a DraggableView. Again,
* we let the Gallery handle the event.
*/
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
}

希望对您有所帮助。

关于Android:将项目拖出滚动列表/画廊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7779025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com