我在网上搜索了一个简单的解决方案来自由移动ImageView
。我终于找到了一些产生完美结果的代码:
public class MainActivity extends Activity implements View.OnTouchListener {
private int _xDelta;
private int _yDelta;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView j = (ImageView)findViewById(R.id.j);
j.setOnTouchListener(this);
}
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
ImageView j = (ImageView)findViewById(R.id.j);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = (int) (X - j.getTranslationX());
_yDelta = (int) (Y - j.getTranslationY());
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
j.setTranslationX(X - _xDelta);
j.setTranslationY(Y - _yDelta);
break;
}
return true;
}}
由于我真的不知道我的代码是如何工作的,所以我想看看是否有更好的解决方案。
答案 0 :(得分:3)
正如Google建议的那样,如果您定位Android 3.0及更高版本,则可以使用DragListener。
对于pre-Honeycomb版本,您可以使用以下内容:
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Remember where we started (for dragging)
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
break;
}
}
return true;
}
再次由Google here建议。
答案 1 :(得分:1)
这是我得到的解决方案:
private float xCoOrdinate, yCoOrdinate;
view.setOnTouchListener(new View.OnTouchListener() {
Float y1 = 0f, y2 = 0f;
@Override
public boolean onTouch(View v, MotionEvent event) {
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//xCoOrdinate = view.getX() - event.getRawX();
yCoOrdinate = view.getY() - event.getRawY();
Float puffer = 0f;
y1 = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
view.animate().y(event.getRawY() + yCoOrdinate).setDuration(0).start();
//view.animate().x(event.getRawX() + xCoOrdinate).y(event.getRawY() + yCoOrdinate).setDuration(0).start();
break;
case MotionEvent.ACTION_UP:
y2 = event.getRawY();
Float dy = (y2 - y1);
if (dy < 0) {
//moved up
view.animate().y(size.y / 100 * -40).setDuration(100).start();
} else if (dy > 0) {
// moved down
view.animate().y(size.y / 2 - view.getHeight() / 2).setDuration(100).start();
}
break;
}
return false;
}
});
说明:如果向上或向下移动,我只需要在y轴上运动和检测。通过将视图设置为触摸动画来完成,女巫有优点和反对(反对:它很复杂,可以检测到视图在空间/专业中的位置:视图实际上移动并且看起来不仅仅是在其他地方)但结果却是为我工作最好,很简单。 这里的目标是向上滑动视图并将其移动到所需的位置,与向下滑动一样,回到原始位置,这与屏幕尺寸相关。 对我而言,代码相对简单且易于解释,但请问是否有任何不清楚的地方。
答案 2 :(得分:0)
由于您使用了来自API级别11的setTranslationX(),因此最好使用DragListener。 http://developer.android.com/guide/topics/ui/drag-drop.html
答案 3 :(得分:0)
这是有效的解决方案
public boolean onTouch(View view, MotionEvent event) {
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();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) view
.getLayoutParams();
ParamsA.leftMargin = X - _xDelta;
ParamsA.topMargin = Y - _yDelta;
ParamsA.rightMargin = -250;
ParamsA.bottomMargin = -250;
for (int i = 0; i < balls.size(); i++) {
if (balls.get(i).getTag() != view.getTag()) {
RelativeLayout.LayoutParams ParamsB = (RelativeLayout.LayoutParams) balls
.get(i).getLayoutParams();
Rect b = new Rect(ParamsB.leftMargin,ParamsB.topMargin,ParamsB.rightMargin,ParamsB.bottomMargin);
Rect a = new Rect(ParamsA.leftMargin,ParamsA.topMargin,ParamsA.rightMargin,ParamsA.bottomMargin);
if(a.intersect(b))
{
Toast.makeText(getApplicationContext(), "Collision Detected", Toast.LENGTH_SHORT).show();
}
}
}
view.setLayoutParams(ParamsA);
break;
}
// _root.invalidate();
return true;
}
欢呼声。
答案 4 :(得分:0)
正在工作
public class MainActivity extends AppCompatActivity {
ImageView imageView;
float xDown = 0;
float yDown = 0;
@SuppressLint("ClickableViewAccessibility")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.subview);
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
xDown = event.getX();
yDown = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveX,moveY;
moveX = event.getX();
moveY = event.getY();
float distanceX = moveX -xDown;
float distanceY = moveY -yDown;
imageView.setX(imageView.getX()+distanceX);
imageView.setY(imageView.getY()+distanceY);
break;
}
return true;
}
});
}
}