我想在我的布局中移动两个不同的视图,以便用户可以像他的意愿一样显示它。
到目前为止,我已经制作了以下代码来处理触摸事件:
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
是处理该位置的自定义对象的实例。
screenHeight
是Display
类给出的屏幕高度。
我能够移动元素,但是当我触摸它时它会闪烁,一旦我把手指放上,视图就会消失。我甚至无法取回它,它只是在屏幕之外。
我做错了吗?
感谢您的帮助
答案 0 :(得分:19)
使用以下代码执行简单的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;
}
});
layout_counter
是您要移动的视图。
不要忘记将您的可移动元素放入FrameLayout
答案 1 :(得分:2)
我创建了移动视图的库:
只需添加依赖项:
dependencies {
compile 'com.scalified:viewmover:1.1.0'
}
您可以在GitHub
找到更多信息答案 2 :(得分:0)
我将为那些使用相对布局的人提供替代解决方案。
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;
}
}
}