I am trying to implement a drag and drop function in Android.I have choosed to implement it using motion event because I think it is easy to understand.I want to make that image I move to remain in the same position and move a duplication. I don't really know how to explain, I want an image on the corner and when I move it the image still remain there but I move another one that is the same, and If I want to move another one from the same position again I move another position.It's like I am trying to get 10 balls from a basket but in this case the basket and the balls are the same image.
My code so far is this:
public class MainActivity extends ActionBarActivity {
private View selected_item = null;
private int offset_x = 0;
private int offset_y = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup vg = (ViewGroup)findViewById(R.id.container);
vg.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked())
{
case MotionEvent.ACTION_MOVE:
int x = (int)event.getX() - offset_x;
int y = (int)event.getY() - offset_y;
int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
if(x > w)
x = w;
if(y > h)
y = h;
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
new ViewGroup.MarginLayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
lp.setMargins(x, y, 0, 0);
selected_item.setLayoutParams(lp);
break;
default:
break;
}
return true;
}
});
ImageView img = (ImageView)findViewById(R.id.newwall);
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
offset_x = (int)event.getX();
offset_y = (int)event.getY();
selected_item = v;
break;
default:
break;
}
return false;
}
});
Also, I am using a ViewGroup and I have a touchListener attached on it.When I am pressing the Layout I am getting the image where I press, I would like when I drop the image to remain there if I touch somewhere else on the screen.I have tried to set selected_item back to null when I end the drag but I didn't make it good I guess because I was getting error and app crashes.
Please help me solve these 2 problems.
Here is what I have used for similar purpose
ImageView snapshot = (ImageView)findViewById(R.id.nonFullScreenSnapshot);
vg.buildDrawingCache();
cache = Bitmap.createBitmap(vg.getDrawingCache());
Drawable drawableShot = new BitmapDrawable(getResources(), cache);
snapshot.setImageDrawable(drawableShot);
snapshot.setVisibility(View.VISIBLE);
In this case I have an ImageView already available from my xml layout, which should be at least as big as the image you want to duplicate.
So when the user touches your ViewGroup you should make a duplicate of it and then position it on the new location.
But be careful with the number of duplicates, because you can easily run out of memory and you will get OutOfMemory exception.
Related
On the following image I would like to detect what part of the human body the on touch event happened. My idea was to have a GridView and determine the position of the human body where the touch event happened. A GridView seems an overkill though. Would it be a better approach with a different layout ?
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
BodyImage item = (BodyImage) parent.getItemAtPosition(position);
switch (position) {
case 0:
// code for head
break;
case 1:
// code for nose
case 2:
// code for n-human part
Here is the image to give the audience an idea
enter image description here
Foremost thanks to Kris Larson for his answer above. The idea is to superpose two images seen here Images to be superposed in the Fragment and hide the image that has the color. The image on the right was colored used the open source Gimp GIMP
Then on the FrameLayout I added the two images Dynamically:
/**
* A Fragment that launches Draw
*/
public static class DrawSectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
boolean touching = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
........
View rootView = inflater.inflate(R.layout.image_superposed, container, false);
// View rootView = inflater.inflate(R.layout.image_superposed, container);
final ImageView iv1 = (ImageView) rootView.findViewById(R.id.imgSecond);
iv1.setImageDrawable(getResources().getDrawable(R.drawable.twocolor1));
final Bitmap bitmap = ((BitmapDrawable)iv1.getDrawable()).getBitmap();
iv1.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
CxMediaPlayer mxMediaPlayer;
mxMediaPlayer = new CxMediaPlayer(getActivity().getBaseContext());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// TODO Auto-generated method stub
touching = true;
Matrix inverse = new Matrix();
iv1.getImageMatrix().invert(inverse);
float[] touchPoint = new float[]{event.getX(), event.getY()};
inverse.mapPoints(touchPoint);
int xCoord = Integer.valueOf((int) touchPoint[0]);
int yCoord = Integer.valueOf((int) touchPoint[1]);
int pixel = bitmap.getPixel(xCoord, yCoord);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
if (pixel == Color.CYAN) {
//mxMediaPlayer = new CxMediaPlayer(getActivity().getBaseContext());
mxMediaPlayer.playShortResource(getActivity().getBaseContext(), 1) ;
}
if (pixel == Color.YELLOW) {
mxMediaPlayer.playShortResource(getActivity().getBaseContext(), 2) ;
}
if (pixel == Color.rgb(0,0,255)) {
CxMediaPlayer mxMediaPlayer1 = new CxMediaPlayer(getActivity().getBaseContext());
mxMediaPlayer1.playShortResource(getActivity().getBaseContext(), 2) ;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
touching = false;
//invalidate();
break;
}
// mxMediaPlayer.Release();
return true;
}
});;
return rootView;
}
Our company did exactly this in our Android app for diagnostic decision support.
We started out with the image of the human form (called a homunculus). Our graphic designer also created transparent overlays of each of the body parts highlighted (to show selection), and also mapped out complex polygons for each area that could be activated by touch. In other words, each touchable area was represented by a set of (x,y) coordinates that roughly outlined the body part.
For the layout, the main container is a FrameLayout containing an ImageView with the homunculus image, overlaid with ImageViews for each highlight image with visibility="gone". An OnTouchListener is used instead of an OnClickListener so that we can get the (x,y) coordinates from the MotionEvent parameter.
In the OnTouchListener, we iterate through all the polygons and hit test to see if a polygon contains the point. If so, then we have our part.
We have a custom Polygon class mainly to do the hit testing. A contains(int x, int y) method was implemented to do the hit testing and used code based on this algorithm: http://alienryderflex.com/polygon/
For drawing the highlight, we have a PolygonDrawable class that creates a Path using the coordinates, creates a PathShape from the path that can be rendered to the UI.
Create a custom ImageView and override onTouch event, you can detect position of user touch.
#Override
public boolean onTouchEvent(MotionEvent event) {
event.getX();// X pos of touch
event.getY();// Y pos of touch
return super.onTouchEvent(event);
}
I want move a bitmap in the screen, but i can do it only horizontally, because if I do it vertically, the scroll of the view start and the movement of the bitmap disappears. I have
public boolean onTouchEvent(MotionEvent event)
method where in case MOVE I change the X and Y of the bitmap. Then in onDraw() method I paint the bitmap. The scroll are in xml. Inside of it are a layout and inside a View.
I would like when I touch, in case DOWN, if I touch the bitmap, disable the scroll, but I is in other place no.
that is the resume of the code
public class Table extends ScrollView{
private static Integer srcX = 0, srcY = 0;
public Table(Context context) {
super(context);
setWillNotDraw(false);
setVerticalScrollBarEnabled(true);
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=1; i<= Paint_Table.num_players; i++)
canvas.drawBitmap(bitmap, X, Y, null);
}
#SuppressLint("ClickableViewAccessibility") #Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
if (youTouchBitmap) {
srcX = x;
srcY = y;
}
break;
case MotionEvent.ACTION_MOVE:
if (srcX !=0 && srcY != 0) {
X=x;
Y=y;
invalidate();
}
break;
}
return true;
}
}
Can someone help me?
Thanks and regards.
since i dont see code ive find some link might help you:
How to disable and enable the scrolling on android ScrollView?
in the link you can see in the answers a code that is custom scroll view its work on flag.
you can choose when the scroll will work ot not.
hope i helpd :)
I'm trying to create something like the unlock activity of the android, where you drag the lock image outside of the circle to unlock the phone. I want to drag an image and to start an activity when it reaches a certain position. I tried doing it with a canvas but it turned out to paint other parts of my screen. So I tried using the following snippet where I found in another post here:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch_ball);
windowwidth = getWindowManager().getDefaultDisplay().getWidth();
windowheight = getWindowManager().getDefaultDisplay().getHeight();
final ImageView balls = (ImageView)findViewById(R.id.ball);
balls.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) balls.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;
layoutParams.topMargin = y_cord;
balls.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}
});
}
But this also doesn't work so well, since when I touch the image it changes its size and also doesn't move smoothly on the screen.
Do you know how can I start an activity, lets say when I drag an image from the bottom of the screen to the top?
This is because of following line
layoutParams.leftMargin = x_cord;
layoutParams.topMargin = y_cord;
balls.setLayoutParams(layoutParams);
If you are setting margins, according to that balls will move.
Where ever i touch on the screen with respect to x y position i need to add one image on that particular position.
I tried by implementing the ontouch listener but it is adding image to different position and many images are being appeared on many touch i want some thing like where ever i touch that same image should appear there
Please Help i am new to android working on project in a compnay
This is my activity code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout rl = (RelativeLayout) findViewById(R.id.wwcontainer);
//Set On TouchListner to the Layout
rl.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("OnTouch", "On Touch View Group....");
int x = (int) event.getX();
int y = (int) event.getY();
ImageView imageView = new ImageView(getApplicationContext());
imageView.setImageResource(R.drawable.icon);
imageView.setLayoutParams(new LayoutParams(x,y));
rl.addView(imageView);
return true;
}
});
}
I know about drag and drop i dont want drag and drop instead i need touch any where there image should appear wrt touch position please help me
I had same request and this is what i done and it worked perfectly for me
final RelativeLayout rr = (RelativeLayout) findViewById(R.id.rr);
rr.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
ImageView iv = new ImageView(getApplicationContext());
lp.setMargins(x, y, 0, 0);
iv.setLayoutParams(lp);
iv.setImageDrawable(getResources().getDrawable(
R.drawable.gr1));
((ViewGroup) v).addView(iv);
}
return false;
}
});
This will place image to RelativeLayout where you touched starting coordinates from there. If you want to center new image where you touched RelativeLayout you need to calculate Height and Width of your image and change one line in my code to
lp.setMargins(x - yourImageWidth/2, y - yourImageHeight/2, 0, 0);
You need to use AbsoluteLayout instead of RelativeLayout.
To add image at particular x,y location, you need AbsoluteLayout.
Did you check what int value getX() and getY() returns i think it will return 0,0.
please use event.getRawX() & event.getRawX() for actual touch position. i hope it will help.
Is there a way in android to get the area (a collection of points) of my finger when i touch the screen. Usually, the return is one point location. I need to get the several points which can represent the area of my touching. Any one knows? Thnaks
Just use View class's onTouchEvent() or implements OnTouchListener in your activity and get the X and Y co-ordinates like,
This is View class's OnTouchEvent()..
#Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
float x = ev.getX();
float y = ev.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
float mLastTouchX = x;
float mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
break;
}
case MotionEvent.ACTION_CANCEL: {
break;
}
case MotionEvent.ACTION_POINTER_UP: {
break;
}
}
return true;
}
EDIT:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView textView = (TextView)findViewById(R.id.textView);
// this is the view on which you will listen for touch events
final View touchView = findViewById(R.id.touchView);
touchView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
textView.setText("Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
return true;
}
});
}
For more details Android - View.
Does it have to be the real shape of the finger? Otherwise you could calculate a circle around the center of the touch.
I believe this is not possible in the touch's coordinate along with it's area. It's natively unsupported by Android API.
Ref:
http://developer.android.com/guide/topics/ui/ui-events.html
http://developer.android.com/reference/android/gesture/package-summary.html
Unfortunately not. I ran in to this a while ago - you could try normalising the data over several 'frames'. May be worth trying to figure out why you need an exact point, or set of points, and find another way of doing it.