Androidで画像をドラッグアンドドロップします
-
13-10-2019 - |
質問
ユーザーが画像を画像に移動できるようにする単語スクランブルゲームに取り組んでいます。画像が一致しない場合、ドラッグされた場所から元の位置に戻る必要があります。画像ですが、ここでの問題は、1つの画像を移動すると、隣接する画像も移動を開始します。ここにサンプルコードがあります。
/** 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>
誰でも私を助けてくれます..それを解決するためにすべての可能なことを試してください。
解決
与えられたボールでイベントが発生していることを確認する必要があります。 Ontouchイベントは、画像オブジェクトの外で触れている場合でも宣言されます。したがって、あなたができることは、タッチがオブジェクトの境界にあることを確認するために、ブロックした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" />
愚かな私...それをもっと注意深く見た後、私はそれがあなたの基本的なアプローチが間違っていることに気付きました。 BallのImageViewにOntouchListenerを設定します。私は実際にボールオブジェクトを作成するだけです。後でそれらと一緒に何かをしたいと思っています。生の座標はどこにでも同様に機能するはずなので、...それを撮影して、それがどのように機能するかを教えてください。
問題は、LinearLayoutが互いに関連している、または垂直に関連するため、LinearLayoutにあります。レイアウトをFrameLayoutまたは非難されたAbsoluTeLayoutに変更するだけです。それはあなたのためにうまくいくでしょう。
私は同様のプログラムを書き、同じ問題を抱えています。私には、プログラム全体に「OntouchListener」を1つしか持たないことができるように思われます。 FrameLayoutを使用していますが、画面に触れると、新しいボールが表示されます。 「framelayout.setontouchListener」を定義すると機能します
既存のボールに触れると、どこかにドラッグしたいと思います。 「ball.setontouchListener」が定義されている場合に機能します。
しかし、私が両方の「setontouchListeners」を使用するとき、それらの1つだけが機能します。
したがって、Androidは1つの「SetontouchListener」だけで動作できると思います。その中には、どのように動的に作成されたボールが触れられたかを確認して処理する必要があります(わかりません)。