Reputation: 421
I have this "Drag and Drop" thingy.
So basically we are making a prototype to let the user (kid) to drag and drop the candy to a jar.
These are the code I have been researching for a while
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);
}
}
these are for the main.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/candy"
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/candy1" >
</ImageView>
</AbsoluteLayout>
However, I want to add other candies to be dragged also. How can I implement this?
Upvotes: 3
Views: 2415
Reputation: 8426
Okay since, your a beginner I'll go through this thoroughly.
The method you have chosen is not ideal for what you're attempting and you might be better of with a custom view and using the Canvas.
However you can still do what you want with this method (and it would avoid a re-write)
The problem here is you have one ImageView
when you want multiple instances of it.
So since you want multiple instances create them dynamically first remove candy from your XML file and then follow this code
ImageView[] candies = new ImageView[10];
for(int i=0;i<candies.length;i++){
candies[i]=new ImageView(this);
// TODO: Set LayoutParams for each imageView
// i.e. AbsoluteLayout.LayoutParams imageParams1 = new AbsoluteLayout.LayoutParams(imageWidth, imageHeight);
candies[i].setBackgroundResource(R.drawable.candy);
layout.addView(candies[i], imageParams1);
}
Now you have 'n' number of candies added to your screen you need to be able to move them.
Your code for the onTouch
will now need to be edited.
Now instead of boolean dragging
make dragging an int
indicating which view is being dragged.
Also instead of
setSameAbsoluteLocation(letterView, emptyLetterView);
use
setSameAbsoluteLocation(v, emptyLetterView);
so the code will work for all views listening (i.e. all the candies). Do this in all letterView
locations in MOUSE_UP
and MOUSE_DOWN
Now in your MOUSE_MOVE
you'll have to do something like this to drag appropriate view
if (v != letterView) {
if (dragging!=-1) {
setAbsoluteLocationCentered(letterView[dragging], x, y);
}
}
Upvotes: 2