Перетаскивание изображений в android
Я работаю над игрой скремблирования слов, которая позволяет пользователю перемещать изображение на изображение..если изображения не совпадают, то она должна вернуться в исходное положение, из которого его вытащили.Я написал пример кода для перемещения изображения, но проблема здесь в том, что если я перемещаю одно изображение, соседнее изображение также начинает двигаться.. Вот пример кода.
/** Touchmoveimage.java*/
package com.examples.Touchmoveimage;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
public class Touchmoveimage extends Activity implements OnTouchListener{
int windowwidth;
int windowheight;
private LayoutParams layoutParams ;
private LayoutParams layoutParams1 ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
windowwidth = getWindowManager().getDefaultDisplay().getWidth();
windowheight = getWindowManager().getDefaultDisplay().getHeight();
ImageView ball= (ImageView)findViewById(R.id.ball);
ball.setOnTouchListener(this);
ImageView ball1 = (ImageView)findViewById(R.id.ball1);
ball1.setOnTouchListener(this);
}
public boolean onTouch(View v,MotionEvent event) {
switch(v.getId())
{
case R.id.ball:
ImageView ball= (ImageView)findViewById(R.id.ball);
layoutParams = (LayoutParams) ball.getLayoutParams();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int)event.getRawX();
int y_cord = (int)event.getRawY();
if(x_cord>windowwidth){x_cord=windowwidth;}
if(y_cord>windowheight){y_cord=windowheight;}
layoutParams.leftMargin = x_cord -25;
layoutParams.topMargin = y_cord - 75;
ball.setLayoutParams(layoutParams);
break;
default : break;
}
case R.id.ball1:
ImageView ball1= (ImageView)findViewById(R.id.ball1);
layoutParams1 = (LayoutParams) ball1.getLayoutParams();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int)event.getRawX();
int y_cord = (int)event.getRawY();
if(x_cord>windowwidth){x_cord=windowwidth;}
if(y_cord>windowheight){y_cord=windowheight;}
layoutParams1.leftMargin = x_cord -25;
layoutParams1.topMargin = y_cord - 75;
ball1.setLayoutParams(layoutParams1);
break;
default : break;
}
}
return true;}
}
<!-- main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:layout_width="50sp"
android:layout_height="50sp"
android:id="@+id/ball"
android:src="@drawable/ball">
</ImageView>
<ImageView
android:layout_y="30dip"
android:layout_x="118dip"
android:layout_width="50sp"
android:layout_height="50sp"
android:id="@+id/ball1"
android:src="@drawable/ball1">
</ImageView>
</LinearLayout>
кто-нибудь plz помогите мне..Пробуя все возможное, чтобы решить ее..
5 ответов
вам нужно убедиться, что событие происходит в данном шаре. Событие onTouch будет объявлено, даже если вы касаетесь внешнего объекта image. Таким образом, вы можете проверить фазы ACTION_DOWN, которые вы заблокировали, чтобы убедиться, что касание находится в границах объекта. Затем вы можете установить флаг, чтобы сообщить системе, какой шар перемещается. Я позволю тебе сделать кодирование, но, надеюсь, это позволит вам получить представление о том, что делать.
Вы можете взять идею из этого кода, это будет очень полезно... и я тоже работаю над этой концепцией.
package com.example.drag;
import android.app.*;
import android.graphics.*;
import android.os.*;
import android.util.Log;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import android.widget.AbsoluteLayout.LayoutParams;
public class MainActivity extends Activity implements OnTouchListener {
// The letter that the user drags.
// The letter outline that the user is supposed to drag letterView to.
private AbsoluteLayout mainLayout;
TextView letterView;
TextView emptyLetterView;
TextView letter_E,letter_I,letter_O,letter_U;
TextView letter_C,letter_T;
int status=0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainLayout = (AbsoluteLayout) findViewById(R.id.absLayout);
mainLayout.setOnTouchListener(this);
letterView = (TextView) findViewById(R.id.imageView);
letterView.setOnTouchListener(this);
emptyLetterView = (TextView) findViewById(R.id.textView1);
letter_E= (TextView) findViewById(R.id.text_E);
letter_I= (TextView) findViewById(R.id.text_I);
letter_O= (TextView) findViewById(R.id.text_O);
letter_U= (TextView) findViewById(R.id.text_U);
letter_C= (TextView) findViewById(R.id.text_C);
letter_T= (TextView) findViewById(R.id.text_T);
letter_I.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
status=2;
return false;
}
});
letter_E.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
status=1;
Log.i("ImageStatus",""+status);
return false;
}
});
AbsoluteLayout abl=(AbsoluteLayout)findViewById(R.id.absLayout);
abl.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Log.i("touch",""+event);
if(status==1) // any event from down and move
{
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,(int)event.getX()-letter_E.getWidth()/2,(int)event.getY()-letter_E.getHeight()/2);
letter_E.setLayoutParams(lp);
}
else if (status==2) {
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,(int)event.getX()-letter_E.getWidth()/2,(int)event.getY()-letter_E.getHeight()/2);
letter_I.setLayoutParams(lp);
}
if(event.getAction()==MotionEvent.ACTION_UP){
status=0;
letter_E.setBackgroundColor(Color.TRANSPARENT);
letter_I.setBackgroundColor(Color.TRANSPARENT);
}
return true;
}
});
Typeface type= Typeface.createFromAsset(getAssets(), "AlphaBalloon.ttf");
letterView.setTypeface(type);
emptyLetterView.setTypeface(type);
letter_E.setTypeface(type);
letter_I.setTypeface(type);
letter_O.setTypeface(type);
letter_U.setTypeface(type);
letter_C.setTypeface(type);
letter_T.setTypeface(type);
}
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);
letterView.setVisibility(View.GONE);
emptyLetterView.setText("A");
emptyLetterView.setTextColor(Color.BLACK);
Toast.makeText(getApplicationContext(), "C for Cat", Toast.LENGTH_SHORT).show();
}
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);
}
}
и XML.....
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/LLayout">
<AbsoluteLayout
android:id="@+id/absLayout"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_alignParentBottom="true" >
<TextView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="10dp"
android:layout_y="-3dp"
android:text="A"
android:textSize="80dp" />
<TextView
android:id="@+id/text_"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="73dp"
android:layout_y="-3dp"
android:text="E"
android:textSize="80dp"/>
<TextView
android:id="@+id/text_I"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="134dp"
android:layout_y="-4dp"
android:text="I"
android:textSize="80dp" />
<TextView
android:id="@+id/text_O"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="196dp"
android:layout_y="-4dp"
android:text="O"
android:textSize="80dp" />
<TextView
android:id="@+id/text_U"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="260dp"
android:layout_y="-4dp"
android:text="U"
android:textSize="80dp" />
<TextView
android:id="@+id/text_T"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="196dp"
android:layout_y="131dp"
android:text="T"
android:textSize="80dp" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="120dp"
android:layout_y="128dp"
android:text="A"
android:textColor="#ffff9f"
android:textSize="80dp" />
<TextView
android:id="@+id/text_C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="45dp"
android:layout_y="129dp"
android:text="C"
android:textSize="80dp" />
</AbsoluteLayout>
<AbsoluteLayout
android:id="@+id/absLayoutNew"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</AbsoluteLayout>
<TextView
android:id="@+id/text_E"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="H"
android:textSize="80dp" />
глупая я... Посмотрев на это более внимательно, я понял, что это ваш фундаментальный подход, который является неправильным. Вы хотите установить onTouchListener на ImageView шара. Я бы просто создал объект шара, вы обязательно захотите что-то сделать с ними позже. Необработанные координаты должны работать так же хорошо, как и везде... Попробуй и дай мне знать, как это работает.
проблема заключается в LinearLayout, поскольку он имеет свои представления, связанные друг с другом, горизонтально или вертикально. Просто измените свой макет на FrameLayout или на устаревший AbsoluteLayout. Для тебя это было бы прекрасно.
Я пытаюсь написать аналогичную программу и иметь ту же проблему. Мне кажется, что во всей программе можно иметь только один "onTouchListener". Я использую FrameLayout, и когда я касаюсь экрана, я хочу, чтобы появился новый шар. Он работает, когда я определяю "FrameLayout.setOnTouchListener"
Если я касаюсь существующего шара, я хочу перетащить его куда-нибудь. Он работает, когда " мяч.setOnTouchListener" определяется.
но когда я использую оба "setOnTouchListeners", чем только один из они работают.
поэтому я думаю, что Android может работать только с одним "setOnTouchListener", и в нем вы должны как-то (я не знаю, как) проверить, какой динамически созданный шар был затронут и обработать его.