Android 在触摸事件上移动视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23120807/
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 move view on touch event
提问by Manitoba
I would like to move two different views into my layout, so that an user can display it like his wishes.
我想将两个不同的视图移动到我的布局中,以便用户可以按照自己的意愿显示它。
So far I've made the following code to handle the touch event:
到目前为止,我已经编写了以下代码来处理触摸事件:
this.viewEvent.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event)
{
final int y = (int) event.getRawY();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
element.setEventY(y - params.topMargin);
break;
case MotionEvent.ACTION_UP:
viewGroup.invalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
params.topMargin = y - element.getEventY();
params.bottomMargin = screenHeight - view.getHeight() - params.topMargin;
// Avoid out of screen
if (params.topMargin < 0) return true;
// Apply changes
view.setLayoutParams(params);
break;
}
return true;
}
});
element
is an instance of a custom object to handle the position.
screenHeight
is the screen height given by the Display
class.
element
是用于处理位置的自定义对象的实例。
screenHeight
是Display
类给出的屏幕高度。
I'm able to move the element but it's blinking when I touch it and once I put my finger up, the view just disapear. I can't even retrieve it, it's just out of the screen.
我可以移动元素,但是当我触摸它时它会闪烁,一旦我抬起手指,视图就会消失。我什至无法检索它,它只是在屏幕外。
Did I make something wrong ?
我做错了什么吗?
Thanks for your help
谢谢你的帮助
回答by Manitoba
USe the following code to perform a simple Touch to move
:
使用以下代码执行一个简单的Touch to move
:
layout_counter.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event)
{
if (currentState != State.EDIT_MOVE) return false;
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
if (view.getId() != R.id.layout_counter) return false;
switch (event.getAction())
{
case MotionEvent.ACTION_MOVE:
params.topMargin = (int) event.getRawY() - view.getHeight();
params.leftMargin = (int) event.getRawX() - (view.getWidth() / 2);
view.setLayoutParams(params);
break;
case MotionEvent.ACTION_UP:
params.topMargin = (int) event.getRawY() - view.getHeight();
params.leftMargin = (int) event.getRawX() - (view.getWidth() / 2);
view.setLayoutParams(params);
break;
case MotionEvent.ACTION_DOWN:
view.setLayoutParams(params);
break;
}
return true;
}
});
Where layout_counter
is the view you want to move.
layout_counter
您要移动的视图在哪里。
Don't forget to put your movable elements into a FrameLayout
不要忘记将可移动元素放入 FrameLayout
回答by Vladyslav Baidak
I created the library, which moves the view:
我创建了移动视图的库:
- For API lower than JellyBean (16) it modifies the view's margins within its parent container
- For API JellyBean and higher it modifies the absolute view position within its parent container
- 对于低于 JellyBean (16) 的 API,它会在其父容器内修改视图的边距
- 对于 API JellyBean 及更高版本,它会修改其父容器内的绝对视图位置
Just add the dependency:
只需添加依赖项:
dependencies {
compile 'com.scalified:viewmover:1.1.0'
}
More info you can find on GitHub
您可以在GitHub 上找到更多信息
回答by Ayaz Alifov
I will provide an alternative solution for those who use Relative layout for example.
例如,我将为那些使用相对布局的人提供替代解决方案。
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class MainActivity extends Activity implements View.OnTouchListener
{
private int _xDelta;
private int _yDelta;
private int _rightMargin;
private int _bottomMargin;
private ImageView _floatingView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this._floatingView = (ImageView) findViewById(R.id.textView);
this._floatingView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
if (_floatingView.getViewTreeObserver().isAlive())
_floatingView.getViewTreeObserver().removeOnPreDrawListener(this);
updateLayoutParams(_floatingView);
return false;
}
});
this._floatingView.setOnTouchListener(this);
}
private void updateLayoutParams(View view)
{
this._rightMargin = -view.getMeasuredWidth();
this._bottomMargin = -view.getMeasuredHeight();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getMeasuredWidth(), view.getMeasuredHeight());
layoutParams.bottomMargin = this._bottomMargin;
layoutParams.rightMargin = this._rightMargin;
view.setLayoutParams(layoutParams);
}
@Override
public boolean onTouch(View view, MotionEvent event)
{
if (view == this._floatingView)
{
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
this._xDelta = X - lParams.leftMargin;
this._yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = X - this._xDelta;
layoutParams.topMargin = Y - this._yDelta;
layoutParams.rightMargin = this._rightMargin;
layoutParams.bottomMargin = this._bottomMargin;
view.setLayoutParams(layoutParams);
break;
}
return true;
}
else
{
return false;
}
}
}