我已经开始上一个问题了,但我想改变拖动的方法。
所以任务是,用户(孩子)学习如何做加法。所以有2个糖果和1个糖果罐。用户需要将糖果拖放到罐子中。怎么做?
这些是我的代码:
主要xml
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLayout">
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/emptyLetterView" android:src="@drawable/r_empty" android:layout_x="200px" android:layout_y="300px"></ImageView>
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/letterView" android:src="@drawable/r_filled" ></ImageView>
</AbsoluteLayout>
这是java文件 package edu.sbcc.cs123.draganddropbasic;
import android.app.*;
import android.graphics.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
@SuppressWarnings("deprecation")
public class DragAndDropBasicActivity extends Activity implements OnTouchListener {
private ImageView letterView; // The letter that the user drags.
private ImageView emptyLetterView; // The letter outline that the user is supposed to drag letterView to.
private AbsoluteLayout mainLayout;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout = (AbsoluteLayout) findViewById(R.id.mainLayout);
mainLayout.setOnTouchListener(this);
letterView = (ImageView) findViewById(R.id.letterView);
letterView.setOnTouchListener(this);
emptyLetterView = (ImageView) findViewById(R.id.emptyLetterView);
}
private boolean dragging = false;
private Rect hitRect = new Rect();
@Override
/**
* NOTE: Had significant problems when I tried to react to ACTION_MOVE on letterView. Kept getting alternating (X,Y)
* locations of the motion events, which caused the letter to flicker and move back and forth. The only solution I could
* find was to determine when the user had touched down on the letter, then process moves in the ACTION_MOVE
* associated with the mainLayout.
*/
public boolean onTouch(View v, MotionEvent event) {
boolean eventConsumed = true;
int x = (int)event.getX();
int y = (int)event.getY();
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
if (v == letterView) {
dragging = true;
eventConsumed = false;
}
} else if (action == MotionEvent.ACTION_UP) {
if (dragging) {
emptyLetterView.getHitRect(hitRect);
if (hitRect.contains(x, y))
setSameAbsoluteLocation(letterView, emptyLetterView);
}
dragging = false;
eventConsumed = false;
} else if (action == MotionEvent.ACTION_MOVE) {
if (v != letterView) {
if (dragging) {
setAbsoluteLocationCentered(letterView, x, y);
}
}
}
return eventConsumed;
}
private void setSameAbsoluteLocation(View v1, View v2) {
AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
setAbsoluteLocation(v1, alp2.x, alp2.y);
}
private void setAbsoluteLocationCentered(View v, int x, int y) {
setAbsoluteLocation(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
}
private void setAbsoluteLocation(View v, int x, int y) {
AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
alp.x = x;
alp.y = y;
v.setLayoutParams(alp);
}
}
这就是我一段时间以来所实施的 我只需添加新变量并将其更改为letterView1和emptyLetterView1
Java文件:
package edu.sbcc.cs123.draganddropbasic;
import android.app.*;
import android.graphics.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
@SuppressWarnings("deprecation")
public class DragAndDropBasicActivity extends Activity implements OnTouchListener {
private ImageView letterView; // The letter that the user drags.
private ImageView emptyLetterView; // The letter outline that the user is supposed to drag letterView to.
private ImageView letterView1; // The letter that the user drags.
private ImageView emptyLetterView1;
private AbsoluteLayout mainLayout;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout = (AbsoluteLayout) findViewById(R.id.mainLayout);
mainLayout.setOnTouchListener(this);
letterView = (ImageView) findViewById(R.id.letterView);
letterView.setOnTouchListener(this);
emptyLetterView = (ImageView) findViewById(R.id.emptyLetterView);
letterView1 = (ImageView) findViewById(R.id.letterView1);
letterView1.setOnTouchListener(this);
emptyLetterView1 = (ImageView) findViewById(R.id.emptyLetterView1);
}
private boolean dragging = false;
private Rect hitRect = new Rect();
@Override
/**
* NOTE: Had significant problems when I tried to react to ACTION_MOVE on letterView. Kept getting alternating (X,Y)
* locations of the motion events, which caused the letter to flicker and move back and forth. The only solution I could
* find was to determine when the user had touched down on the letter, then process moves in the ACTION_MOVE
* associated with the mainLayout.
*/
public boolean onTouch(View v, MotionEvent event) {
boolean eventConsumed = true;
int x = (int)event.getX();
int y = (int)event.getY();
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
if (v == letterView) {
dragging = true;
eventConsumed = false;
}
if (v == letterView1) {
dragging = true;
eventConsumed = false;
}
} else if (action == MotionEvent.ACTION_UP) {
if (dragging) {
emptyLetterView.getHitRect(hitRect);
if (hitRect.contains(x, y))
setSameAbsoluteLocation(letterView, emptyLetterView);
}
if (dragging) {
emptyLetterView1.getHitRect(hitRect);
if (hitRect.contains(x, y))
setSameAbsoluteLocation1(letterView1, emptyLetterView1);
}
dragging = false;
eventConsumed = true;
} else if (action == MotionEvent.ACTION_MOVE) {
if (v != letterView) {
if (dragging) {
setAbsoluteLocationCentered(letterView, x, y);
}
}
if (v != letterView1) {
if (dragging) {
setAbsoluteLocationCentered1(letterView1, x, y);
}
}
}
return eventConsumed;
}
private void setSameAbsoluteLocation(View v1, View v2) {
AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
setAbsoluteLocation(v1, alp2.x, alp2.y);
}
private void setAbsoluteLocationCentered(View v, int x, int y) {
setAbsoluteLocation(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
}
private void setAbsoluteLocation(View v, int x, int y) {
AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
alp.x = x;
alp.y = y;
v.setLayoutParams(alp);
}
private void setSameAbsoluteLocation1(View v1, View v2) {
AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
setAbsoluteLocation1(v1, alp2.x, alp2.y);
}
private void setAbsoluteLocationCentered1(View v, int x, int y) {
setAbsoluteLocation1(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
}
private void setAbsoluteLocation1(View v, int x, int y) {
AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
alp.x = x;
alp.y = y;
v.setLayoutParams(alp);
}
}
我已将图像文件添加到xml文件中,并将id更改为letterView1和emptyLetterView1。
因此,成功显示了另一个图像,但是当我拖动其中一个图像时,另一个图像消失了。
我该如何实现呢?
答案 0 :(得分:3)
我的解决方案基于以下代码/信息:
答案 1 :(得分:1)
您的代码存在问题
else if (action == MotionEvent.ACTION_MOVE) {
if (v != letterView) {
if (dragging) {
setAbsoluteLocationCentered(letterView, x, y);
}
}
if (v != letterView1) {
if (dragging) {
setAbsoluteLocationCentered1(letterView1, x, y);
}
}
}
现在在你早期的代码中有2个听众。
letterView
现在你有3个听众,所以如果用户在地面或信件上拖动,if (v != letterView)
将是真的。
例如,如果您开始拖动随机的屏幕补丁,则v!=letterView
和v!=letterView1
。它们都会居中到同一点,所以人们会隐藏它们。
如果拖动其中一个,则相同。另一个将移动到那一点,它将显示为隐藏。
您可以尝试
,而不是使用非方程式else if (action == MotionEvent.ACTION_MOVE) {
if (v == letterView) {
if (dragging) {
setAbsoluteLocationCentered(letterView, x, y);
}
}
if (v == letterView1) {
if (dragging) {
setAbsoluteLocationCentered1(letterView1, x, y);
}
}
}
或者你甚至可以进行命中测试
else if (action == MotionEvent.ACTION_MOVE) {
letterView.getHitRect(hitRect);
if (letterView.contains(x,y)) {
if (dragging) {
setAbsoluteLocationCentered(letterView, x, y);
}
}
letterView1.getHitRect(hitRect);
if (letterView1.contains(x,y)) {
if (dragging) {
setAbsoluteLocationCentered1(letterView1, x, y);
}
}
}