视图的 Android 拖动/动画
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2363666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Drag/Animation of Views
提问by Peter
I'm not a programmer, but I'm trying to learn android development, and having a blast.
我不是程序员,但我正在尝试学习 android 开发,并且玩得很开心。
Lately I've hit a fork in the road, and I don't know that any of the directions I can identify will meet all my needs. This is where you (the experts) can help ;)
最近我遇到了一个岔路口,我不知道我能确定的任何方向都能满足我的所有需求。这是您(专家)可以提供帮助的地方;)
Endpoint: I want to have the user touch a ball, and drag it to any location on the screen. I would also like to animate this ball when it gets drawn, and when it gets dropped.
端点:我想让用户触摸一个球,并将其拖动到屏幕上的任何位置。我还想在这个球被绘制和掉落时设置动画。
I can accomplish the dragging part using a custom class (that doesn't extend anything... just a class like is found in this tutorial: basic drag & drop, however, I don't know how to apply the tween animation to it since it's not a view.
我可以使用自定义类来完成拖动部分(不会扩展任何东西......只是在本教程中找到了一个类:基本拖放,但是,我不知道如何将补间动画应用于它因为它不是视图。
I have also developed an animated version of an ImageView with my image in it, however, I can't manage to apply the same drag & drop functionality without using AbsoluteLayout, which I know is a no-no.
我还开发了一个 ImageView 的动画版本,其中包含我的图像,但是,如果不使用 AbsoluteLayout,我就无法应用相同的拖放功能,我知道这是禁忌。
So... how do I move an ImageView around a ??? layout using MotionEvents, or how do I animate (using tweens defined in XML) a non-view based custom class?
那么......我如何在 ??? 周围移动 ImageView 使用 MotionEvents 进行布局,或者如何为非基于视图的自定义类设置动画(使用 XML 中定义的补间)?
Please ask questions if this is not clear. I don't know all the terminology as well as most of you might.
如果不清楚,请提出问题。我不像你们大多数人那样了解所有的术语。
There is also a copyof this question on the anddev.org forums, so I'll keep this post updated with any responses I get over there.
在 anddev.org 论坛上也有这个问题的副本,所以我会根据我在那里得到的任何回复来更新这篇文章。
回答by CaseyB
Why can't you extend View? Then, you have complete control over how it draws because you can override the OnDraw() method. Just make the ColorBall class extend View. Change its position when you move and then invalidate just that one view and have it draw itself instead of having the DrawView class draw it.
为什么不能扩展视图?然后,您可以完全控制它的绘制方式,因为您可以覆盖 OnDraw() 方法。只需让 ColorBall 类扩展 View。当你移动时改变它的位置,然后使那个视图无效并让它自己绘制而不是让 DrawView 类绘制它。
Edit - Here is an example class
编辑 - 这是一个示例类
public class Card extends View
{
private Bitmap mImage;
private final Paint mPaint = new Paint();
private final Point mSize = new Point();
private final Point mStartPosition = new Point();
public Card(Context context)
{
super(context);
}
public final Bitmap getImage() { return mCardImage; }
public final void setImage(Bitmap image)
{
mImage = image;
setSize(mCardImage.getWidth(), mCardImage.getHeight());
}
@Override
protected void onDraw(Canvas canvas)
{
Point position = getPosition();
canvas.drawBitmap(mCardImage, position.x, position.y, mPaint);
}
public final void setPosition(final Point position)
{
mRegion.set(position.x, position.y, position.x + mSize.x, position.y + mSize.y);
}
public final Point getPosition()
{
Rect bounds = mRegion.getBounds();
return new Point(bounds.left, bounds.top);
}
public final void setSize(int width, int height)
{
mSize.x = width;
mSize.y = height;
Rect bounds = mRegion.getBounds();
mRegion.set(bounds.left, bounds.top, bounds.left + width, bounds.top + height);
}
public final Point getSize() { return mSize; }
@Override
public boolean onTouchEvent(MotionEvent event)
{
// Is the event inside of this view?
if(!mRegion.contains((int)event.getX(), (int)event.getY()))
{
return super.onTouchEvent(event);
}
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
bringToFront();
onSelected();
return true;
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
int x = 0, y = 0;
if(mLock == DirectionLock.FREE || mLock == DirectionLock.HORIZONTAL_ONLY)
{
x = (int)event.getX() - mStartPosition.x;
}
if(mLock == DirectionLock.FREE || mLock == DirectionLock.VERTICAL_ONLY)
{
y = (int)event.getY() - mStartPosition.y;
}
mRegion.translate(x, y);
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
invalidate();
return true;
}
else
{
return super.onTouchEvent(event);
}
}
}