Reputation: 558
I am presently developing this kind of view.
My Target API version will be API5.
Left Side A,B,C,D refers to reference Images(These are not Clickable) Downside shown Images are the "Draggable" ones.They are shuffled. Now the user has to Drag the bottom images and drop them in the corresponding "Droppable Area" on the right side of the screen.
And am using , this kind of Layout:
.xml format:
<LinearLayout id="@+id/container"
orientation="vertical">
<LinearLayout android:orientation="horizontal"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher">
<ImageView android:src="#FFFFFF"
android"id="@+id/img">
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher">
<ImageView android:src="#FFFFFF"
android"id="@+id/img1">
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher">
<ImageView android:src="#FFFFFF"
android"id="@+id/img2">
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher">
<ImageView android:src="#FFFFFF"
android"id="@+id/img3">
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher"
android:id="@+id/imgDrop"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher"
android:id="@+id/imgDrop1"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher"
android:id="@+id/imgDrop2"
android:weight="1">
<ImageView android:src="@drawable/ic_launcher"
android:id="@+id/imgDrop3"
android:weight="1">
</LinearLayout>
And for MainActivity , I tried the following code to drag & drop for Single Image from the developer website and StackOverFlow using the following code , it is working:
MainActivity.java:
public class MainActivity extends Activity implements OnTouchListener {
private View selected_item = null;
private int offset_x = 0;
private int offset_y = 0;
Boolean touchFlag=false;
boolean dropFlag=false;
LayoutParams imageParams;
ImageView imageDrop,image1,image2;
int crashX,crashY;
Drawable dropDrawable,selectDrawable;
Rect dropRect,selectRect;
int topy,leftX,rightX,bottomY;
int dropArray[];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup container = (ViewGroup) findViewById(R.id.container);
imageDrop=(ImageView) findViewById(R.id.ImgDrop);
image1=(ImageView) findViewById(R.id.img);
image2=(ImageView) findViewById(R.id.img2);
container.setBackgroundColor(Color.GREEN);
container.setOnTouchListener(new View.OnTouchListener()
{
@SuppressWarnings("deprecation")
public boolean onTouch(View v, MotionEvent event)
{
if(touchFlag==true)
{
System.err.println("Display If Part ::->"+touchFlag);
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN :
topy=imageDrop.getTop();
leftX=imageDrop.getLeft();
rightX=imageDrop.getRight();
bottomY=imageDrop.getBottom();
System.err.println("Display Top-->"+topy);
System.err.println("Display Left-->"+leftX);
System.err.println("Display Right-->"+rightX);
System.err.println("Display Bottom-->"+bottomY);
//opRect.
break;
case MotionEvent.ACTION_MOVE:
crashX=(int) event.getX();
crashY=(int) event.getY();
System.err.println("Display Here X Value-->"+crashX);
System.err.println("Display Here Y Value-->"+crashY);
int x = (int) (event.getX() - offset_x);
int y = (int) (event.getY() - offset_y);
int w = getWindowManager().getDefaultDisplay().getWidth() - 50;
int h = getWindowManager().getDefaultDisplay().getHeight() - 10;
if (x > w)
x = w;
if (y > h)
y = h;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
lp.setMargins(x, y, 0, 0);
//Drop Image Here
if(crashX > leftX && crashX < rightX && crashY > topy && crashY < bottomY )
{
Drawable temp=selected_item.getBackground();
imageDrop.setBackgroundDrawable(temp);
imageDrop.bringToFront();
dropFlag=true;
selected_item.setVisibility(View.INVISIBLE);
}
//Drop Image Here
selected_item.setLayoutParams(lp);
break;
case MotionEvent.ACTION_UP:
//
touchFlag=false;
if(dropFlag==true)
{
dropFlag=false;
}
else
{
selected_item.setLayoutParams(imageParams);
}
break;
default:
break;
}
}else
{
System.err.println("Display Else Part ::->"+touchFlag);
}
return true;
}
});
image1.setOnTouchListener(this);
image2.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
touchFlag=true;
offset_x = (int) event.getX();
offset_y = (int) event.getY();
selected_item = v;
imageParams=v.getLayoutParams();
break;
case MotionEvent.ACTION_UP:
selected_item=null;
touchFlag=false;
break;
default:
break;
}
return false;
} }
My question is how to achieve the way of logic I need as shown in the Image above.
Any Kind of Suggestions OR references are highly appreciable. Thanks.
Upvotes: 0
Views: 2812
Reputation: 856
Check if this is helpful
Create a new class MultiTouchListener that implements OnTouchListener
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class MultiTouchListener implements OnTouchListener
{
private float mPrevX;
private float mPrevY;
public MainActivity mainActivity;
public MultiTouchListener(MainActivity mainActivity1) {
mainActivity = mainActivity1;
}
@Override
public boolean onTouch(View view, MotionEvent event) {
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN: {
mPrevX = event.getX();
mPrevY = event.getY();
break;
}
case MotionEvent.ACTION_MOVE:
{
// Find the index of the active pointer and fetch its position.
float currX = event.getX();
float currY = event.getY();
adjustTranslation(view, currX - mPrevX, currY - mPrevY);
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
private static void adjustTranslation(View view, float deltaX, float deltaY)
{
float[] deltaVector = { deltaX, deltaY };
view.getMatrix().mapVectors(deltaVector);
view.setTranslationX(view.getTranslationX() + deltaVector[0]);
view.setTranslationY(view.getTranslationY() + deltaVector[1]);
}
}
Now in MainActivity,suppose imgDrop is the draggable image, then apply a touchListener to this image as:
MultiTouchListener touchListener=new MultiTouchListener(this);
imgDrop.setOnTouchListener(touchListener);
This will apply a touchListener to ur imageView. Now to implement ur logic. First in MainActivity assign a tag to each imageView where you have to drop ur draggable Images (The White imageViews).I have assumed those as base1,base2 and so on..
//Some Global Declarations
ImageView base;
float v_origX,v_origY; // Used for original X and Y of ImageViews
//In OnCreate() of MainActivity
base1.setTag(0);
base2.setTag(1);
base3.setTag(2);
base4.setTag(3);
// Function to check Tag for the base imageView
public void checkTag(Object tag)
{
if(tag.equals(0))
base=(ImageView)findViewById(R.id.base1);
else if(tag.equals(1))
base=(ImageView)findViewById(R.id.base2);
else if(tag.equals(2))
base=(ImageView)findViewById(R.id.base3);
else if(tag.equals(3))
base=(ImageView)findViewById(R.id.base4);
tag=this.tag;
//You can get the X and Y and the corresponding width and height for the imageViews to apply the logic for intersection
/* b_x=base.getX();
b_y=base.getY();
b_x_width=base.getX()+base.getWidth();
b_y_height=base.getY()+base.getHeight(); */
}
/////////// Check the Intersection of Images (Drag and Drop)
public void checkIntersection(View imgView)
{
ImageView view=(ImageView)findViewById(imgView.getId());
// You can get the X and Y coordinates and width and height of the Dragged ImageView as
/* v_x=view.getX();
v_y=view.getY();
v_x_width=view.getX()+view.getWidth();
v_y_height=view.getY()+view.getHeight(); */
if( Comparison of X and Y coordinates of dragged ImageViews and base ImageView)
{
// Stuff if Intersection is correct
}
else
{
// Move the imageView back to their original position if matching sequence is wrong
view.setX(v_origX);
view.setY(v_origY);
}
}
// Just a few lines more to be updated in your MultiTouchListener // Update ACTION_DOWN with
case MotionEvent.ACTION_DOWN: {
//Get the original x and y coordinates
mainActivity.v_origX=view.getX();
mainActivity.v_origY=view.getY();
}
and in ACTION_UP, add
case MotionEvent.ACTION_UP:
mainActivity.checkTag(view.getTag());
mainActivity.checkIntersection(view);
Upvotes: 2