Android:onTouchListener无法正常工作
我目前正在开发一个应用程序,它有一个Android:onTouchListener无法正常工作,android,android-layout,ontouchlistener,Android,Android Layout,Ontouchlistener,我目前正在开发一个应用程序,它有一个RelativeLayout,它有4个子FrameLayouts,每个FrameLayout内部都有一组图像视图,内部视图有自己的行为。在实现我在中找到的onTouchListener时,我正在尝试实现拖放到FrameLayouts。但不幸的是,拖放不能正常工作,什么也没有发生 关于如何正确实现拖放功能有什么想法吗?我错过了什么 以下是FrameLayouts的单个子级的xml代码: <?xml version="1.0" encoding="utf-
RelativeLayout
,它有4个子FrameLayouts
,每个FrameLayout内部都有一组图像视图,内部视图有自己的行为。在实现我在中找到的onTouchListener
时,我正在尝试实现拖放到FrameLayouts
。但不幸的是,拖放不能正常工作,什么也没有发生
关于如何正确实现拖放功能有什么想法吗?我错过了什么
以下是
FrameLayouts
的单个子级的xml代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
android:layout_height="108dp" >
<ImageView
android:id="@+id/secondImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/back" />
<ImageView
android:id="@+id/firstImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/c2" />
</FrameLayout>
以下是针对单个孩子的Java代码:
public class Card implements OnClickListener {
private int _resId;
private Context _context;
private ImageView firstImage, secondImage;
private boolean isFirst;
public Card(Context context, FrameLayout parent) {
_context = context;
firstImage = (ImageView) parent.findViewById(R.id.firstImage);
secondImage = (ImageView) parent.findViewById(R.id.secondImage);
}
public void setupCards(int resId, boolean hasBackSide) {
_resId = resId;
Bitmap temp = BitmapFactory.decodeResource(_context.getResources(),
_resId);
firstImage.setImageBitmap(temp);
if (hasBackSide) {
temp = BitmapFactory.decodeResource(_context.getResources(),
R.drawable.back);
}
secondImage.setImageBitmap(temp);
isFirst = true;
secondImage.setVisibility(View.GONE);
}
// MORE IMPLEMENTATION
}
这是我的主要活动Java代码:
public class FaceUpActivity extends Activity {
FrameLayout firstCard, secondCard, thirdCard, forthCard;
Card cardNumber1, cardNumber2, cardNumber3, cardNumber4;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initUI();
}
private void initUI() {
firstCard = (FrameLayout) findViewById(R.id.cardNumber1);
secondCard = (FrameLayout) findViewById(R.id.cardNumber2);
thirdCard = (FrameLayout) findViewById(R.id.cardNumber3);
forthCard = (FrameLayout) findViewById(R.id.cardNumber4);
cardNumber1 = new Card(this, firstCard);
cardNumber2 = new Card(this, secondCard);
cardNumber3 = new Card(this, thirdCard);
cardNumber4 = new Card(this, forthCard);
cardNumber1.setupCards(R.drawable.c2, true);
cardNumber2.setupCards(R.drawable.d0, true);
cardNumber3.setupCards(R.drawable.h5, true);
cardNumber4.setupCards(R.drawable.sj, true);
firstCard.setOnTouchListener(dragMe);
secondCard.setOnTouchListener(dragMe);
thirdCard.setOnTouchListener(dragMe);
forthCard.setOnTouchListener(dragMe);
}
OnTouchListener dragMe = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
FrameLayout.LayoutParams params = (LayoutParams) v
.getLayoutParams();
int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
int maxHeight = getWindowManager().getDefaultDisplay().getHeight();
int topMargin, leftMargin;
int cond = v.getId();
if (cond == R.id.cardNumber1 || cond == R.id.cardNumber2
|| cond == R.id.cardNumber3 || cond == R.id.cardNumber4) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
topMargin = (int) event.getRawY() - (v.getHeight());
leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;
if (topMargin < 0) {
params.topMargin = 0;
} else if (topMargin > maxHeight) {
params.topMargin = maxHeight - v.getHeight();
} else {
params.topMargin = topMargin;
}
if (leftMargin < 0) {
params.leftMargin = 0;
} else if (leftMargin > maxWidth) {
params.leftMargin = maxWidth - (v.getWidth() / 2);
} else {
params.leftMargin = leftMargin;
}
v.setLayoutParams(params);
break;
case MotionEvent.ACTION_MOVE:
topMargin = (int) event.getRawY() - (v.getHeight());
leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;
if (topMargin < 0) {
params.topMargin = 0;
} else if (topMargin > maxHeight) {
params.topMargin = maxHeight - v.getHeight();
} else {
params.topMargin = topMargin;
}
if (leftMargin < 0) {
params.leftMargin = 0;
} else if (leftMargin > maxWidth) {
params.leftMargin = maxWidth - (v.getWidth() / 2);
} else {
params.leftMargin = leftMargin;
}
v.setLayoutParams(params);
break;
}
}
return true;
}
};
}
公共类FaceUpActivity扩展活动{
框架布局第一张卡、第二张卡、第三张卡、第四张卡;
卡号1、卡号2、卡号3、卡号4;
/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initUI();
}
私有void initUI(){
firstCard=(FrameLayout)findviewbyd(R.id.cardNumber1);
secondCard=(FrameLayout)findViewById(R.id.cardNumber2);
thirdCard=(FrameLayout)findViewById(R.id.cardNumber3);
forthCard=(FrameLayout)findviewbyd(R.id.cardNumber4);
cardNumber1=新卡(这是第一张卡);
cardNumber2=新卡(这是第二张卡);
cardNumber3=新卡(这是第三张卡);
cardNumber4=新卡(此为forthCard);
卡号1.设置卡(R.drawable.c2,真);
卡号2.设置卡(R.drawable.d0,真);
卡号3.设置卡(R.drawable.h5,正确);
卡号4.设置卡(R.drawable.sj,真);
firstCard.setOnTouchListener(dragMe);
secondCard.setOnTouchListener(dragMe);
第三张卡片:setOnTouchListener(dragMe);
forthCard.SETONTOUCH侦听器(dragMe);
}
OnTouchListener dragMe=新的OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
FrameLayout.LayoutParams参数=(LayoutParams)v
.getLayoutParams();
int maxWidth=getWindowManager().getDefaultDisplay().getWidth();
int maxHeight=getWindowManager().getDefaultDisplay().getHeight();
int-topMargin,leftMargin;
int cond=v.getId();
如果(cond==R.id.cardNumber1 | | cond==R.id.cardNumber2
||cond==R.id.cardNumber3 | | cond==R.id.cardNumber4){
开关(event.getAction()){
case MotionEvent.ACTION\u UP:
topMargin=(int)event.getRawY()-(v.getHeight());
leftMargin=(int)event.getRawX()-(v.getWidth())/2;
如果(上边距<0){
params.topMargin=0;
}否则如果(topMargin>maxHeight){
params.topMargin=maxHeight-v.getHeight();
}否则{
params.topMargin=topMargin;
}
如果(左边距<0){
params.leftMargin=0;
}else if(leftMargin>maxWidth){
params.leftMargin=maxWidth-(v.getWidth()/2);
}否则{
params.leftMargin=leftMargin;
}
v、 setLayoutParams(参数);
打破
case MotionEvent.ACTION\u移动:
topMargin=(int)event.getRawY()-(v.getHeight());
leftMargin=(int)event.getRawX()-(v.getWidth())/2;
如果(上边距<0){
params.topMargin=0;
}否则如果(topMargin>maxHeight){
params.topMargin=maxHeight-v.getHeight();
}否则{
params.topMargin=topMargin;
}
如果(左边距<0){
params.leftMargin=0;
}else if(leftMargin>maxWidth){
params.leftMargin=maxWidth-(v.getWidth()/2);
}否则{
params.leftMargin=leftMargin;
}
v、 setLayoutParams(参数);
打破
}
}
返回true;
}
};
}
我认为存在两个潜在问题:
onTouch()
中获得了正确的ID吗?(由于touch listener仅用于卡视图,因此如果检查ID,您可以删除)
FrameLayout
-因此使用x和y位置而不是边距编辑:我的错,您使用的是RelativeLayout
,因此边距有点正确。不过,我会使用FrameLayout
onTouch()
中返回true
,否则返回false
(您没有移动卡时返回true
,移动卡时什么也没有返回)为什么您的D&D不起作用: D&D不起作用,因为您的卡(使用内部框架布局)正在实现onClick事件,该事件“吃掉”D&D事件 解决办法有两个: 您可以有两个不同的区域,一个用于单击事件(卡的最大部分),一个用于d&d事件(卡的左下边缘)。您可以在实现此解决方案的Android音乐播放器中看到一个实例 否则,您可以同时处理这两个事件:
- 在相同的x/y位置,在相同的时间内(100毫秒以下)单击==向下+向上
- dd==在不同的位置向下+向上
public class FaceUpActivity extends Activity { FrameLayout firstCard, secondCard, thirdCard, forthCard; Card cardNumber1, cardNumber2, cardNumber3, cardNumber4; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initUI(); } private void initUI() { firstCard = (FrameLayout) findViewById(R.id.cardNumber1); secondCard = (FrameLayout) findViewById(R.id.cardNumber2); thirdCard = (FrameLayout) findViewById(R.id.cardNumber3); forthCard = (FrameLayout) findViewById(R.id.cardNumber4); cardNumber1 = new Card(this, firstCard); cardNumber2 = new Card(this, secondCard); cardNumber3 = new Card(this, thirdCard); cardNumber4 = new Card(this, forthCard); cardNumber1.setupCards(R.drawable.c2, true); cardNumber2.setupCards(R.drawable.d0, true); cardNumber3.setupCards(R.drawable.h5, true); cardNumber4.setupCards(R.drawable.sj, true); firstCard.setOnTouchListener(dragMe); secondCard.setOnTouchListener(dragMe); thirdCard.setOnTouchListener(dragMe); forthCard.setOnTouchListener(dragMe); } OnTouchListener dragMe = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { FrameLayout.LayoutParams params = (LayoutParams) v .getLayoutParams(); int maxWidth = getWindowManager().getDefaultDisplay().getWidth(); int maxHeight = getWindowManager().getDefaultDisplay().getHeight(); int topMargin, leftMargin; int cond = v.getId(); if (cond == R.id.cardNumber1 || cond == R.id.cardNumber2 || cond == R.id.cardNumber3 || cond == R.id.cardNumber4) { switch (event.getAction()) { case MotionEvent.ACTION_UP: topMargin = (int) event.getRawY() - (v.getHeight()); leftMargin = (int) event.getRawX() - (v.getWidth()) / 2; if (topMargin < 0) { params.topMargin = 0; } else if (topMargin > maxHeight) { params.topMargin = maxHeight - v.getHeight(); } else { params.topMargin = topMargin; } if (leftMargin < 0) { params.leftMargin = 0; } else if (leftMargin > maxWidth) { params.leftMargin = maxWidth - (v.getWidth() / 2); } else { params.leftMargin = leftMargin; } v.setLayoutParams(params); break; case MotionEvent.ACTION_MOVE: topMargin = (int) event.getRawY() - (v.getHeight()); leftMargin = (int) event.getRawX() - (v.getWidth()) / 2; if (topMargin < 0) { params.topMargin = 0; } else if (topMargin > maxHeight) { params.topMargin = maxHeight - v.getHeight(); } else { params.topMargin = topMargin; } if (leftMargin < 0) { params.leftMargin = 0; } else if (leftMargin > maxWidth) { params.leftMargin = maxWidth - (v.getWidth() / 2); } else { params.leftMargin = leftMargin; } v.setLayoutParams(params); break; } } return true; } }; }