Hello i would like to ask, how can i Display Toast near the user click point Like on image below using GraphView library:
http://android-graphview.org/
Thanks for any advice
EDIT:
I tried it using
seriesSin = new GraphViewSeries("Sinus curve", new GraphViewSeries.GraphViewSeriesStyle(Color.rgb(200, 50, 00), 3), data);
// SET ON TOUCH
graphView.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
int size = seriesSin.size();
float screenX = event.getX();
float screenY = event.getY();
float width_x = v.getWidth();
float viewX = screenX - v.getLeft();
float viewY = screenY - v.getTop();
float percent_x = (viewX/width_x);
int pos = (int) (size*percent_x);
System.out.println("X: " + viewX + " Y: " + viewY +" Percent = " +percent_x);
System.out.println("YVal = " +seriesSin.getY(pos));
return true;
}
return false;
}
});
But I cannot to get seriesSin.size and seriesSin.getY(pos)
You can't decide where to display the Toast. However, you could set up a custom view and show it using the coordinates (x and y) you get when detecting the touch. When you show the view, simply use those values to set up the layout params of the view, and voila.
Version 4.0.0 added an onTap() listener, that replicates your onTouch method above, it doesn't solve your Toast positioning issue, but could save you a few lines of code.
Related
I am trying to get coordinates of frame layout present in my screen in android.
I tried getLocationOnScreen but it is giving me 0. How to get the right value?
int[] location = new int[2];
face_oval_layout.getLocationOnScreen(location);
Util.log("X axis is " + location[0] + "and Y axis is " + location[1]);
Above snippet called inside camera take picture callback. Value of X and Y, both are 0.
frmLayout = (FrameLayout)findViewById(R.id.frameLayout1);
frmLayout.setFocusable(true);
EditText et = new EditText(this);
frmLayout.addView(et,100,100);
frmLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TESTING","touch x,y == " + event.getX() + "," + event.getY() );
frmLayout.setPadding(Math.round(event.getX()),Math.round(event.getY()) , 0, 0);
return true;
}
});
I have a gridview that I need to implement drag and drop feature. I've been trying to find a possible solution or existing library that would fit my problem but still no luck.
Here's a before and after illustration of the drag and drop that I need to implement:
The red tiles are items wherein they cannot be dragged nor dropped on. the blue ones are draggable and can be dropped on any tile on any row, just not on the red tiles. The white tiles are just placeholders which are placed to have the red tiles on the first column.
Now, when tile A is dragged on the 3rd row, as you can see, they go side by side, not swapped, even if put on top of tile C. The number of white tiles is depending on the number of blue tiles per row, an arraylist is assigned on each row, so it'll just follow. My real problem is that all examples on gridview drag and drop is that tiles swaps or the whole grid follows the flow of items.
My plan to implement this:
When long pressed on a tile to be dragged, it will show a tile that looks like that tile, only larger and lesser opacity.
When dropped on a certain position, will compute for the row.
Adjust arraylists and notifydatasetchanged.
Here's breaking down the problem to slightly smaller problems:
How can I make a larger tile of the long pressed tile?
Is it possible to get the position where the enlarged tile is dropped?
1.How can I make a larger tile of the long pressed tile? yes,you can get the tile's view and create a new bitmap,the add the bitmap to Windows.Like this : it's a class extends GridView.
public boolean setOnItemLongClickListener(final MotionEvent ev)
{
this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3)
{
// onInterceptTouchEvent(ev);
// TODO Auto-generated method stub
L.l("============on Long Click=========");
L.l("============X:" + ev.getX() + " Y:" + ev.getY());
int x = (int) ev.getX();
int y = (int) ev.getY();
dragPosition = dropPosition = pointToPosition(x, y);
System.out.println(dragPosition);
if (dragPosition == AdapterView.INVALID_POSITION)
{
}
ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
- getFirstVisiblePosition());
dragPointX = x - itemView.getLeft();
dragPointY = y - itemView.getTop();
dragOffsetX = (int) (ev.getRawX() - x);
dragOffsetY = (int) (ev.getRawY() - y);
itemHeight=itemView.getHeight();
L.l("========================y:" + y + " getRawY:"
+ ev.getRawY());
itemView.destroyDrawingCache();
itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
startDrag(bm, x, y);
return false;
};
});
return super.onInterceptTouchEvent(ev);
}
private void startDrag(Bitmap bm, int x, int y)
{
windowParams = new WindowManager.LayoutParams();
windowParams.gravity = Gravity.TOP | Gravity.LEFT;// 这个必须加
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
windowParams.format = PixelFormat.TRANSLUCENT;
windowParams.windowAnimations = 0;
ImageView iv = new ImageView(getContext());
iv.setImageBitmap(bm);
windowManager = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);// "window"
windowManager.addView(iv, windowParams);
dragImageView = iv;
}
#Override
public boolean onTouchEvent(MotionEvent ev)
{
if (dragImageView != null
&& dragPosition != AdapterView.INVALID_POSITION)
{
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.getAction())
{
case MotionEvent.ACTION_MOVE:
onDrag(x, y);
break;
case MotionEvent.ACTION_UP:
stopDrag();
onDrop(x, y);
break;
}
}
return super.onTouchEvent(ev);
}
private void onDrag(int x, int y)
{
if (dragImageView != null)
{
windowParams.alpha = 0.6f;
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
// L.l("=================windowParams.y=====000========"+windowParams.y);
windowManager.updateViewLayout(dragImageView, windowParams);
}
int tempScrollX = x - dragPointX + dragOffsetX;
int tempScrollY = y - dragPointY + dragOffsetY;
if (tempScrollY +itemHeight> 600)
{
this.scrollTo(0, tempScrollY);
}
else
if (pointToPosition(x, y) > 2)
{
this.scrollTo(0, tempScrollY - 300);
}
}
2.Is it possible to get the position where the enlarged tile is dropped?
If your class is extends GridView or AbsListView,this API `pointToPosition(x, y) will return the position of the whole view.
When you drop tile A,then you calculate where tile A is now,if above tile C,then start a Animation(C move to side and A take place position of C) and update the Adapter end of the Animation.
I ended up editting http://code.google.com/p/android-gridview-drag-and-drop/ to fit my problem.
I have a linear layout that I have assigned an onTouchListener. I have gotten the width and height of the device but the problem is, the origin is at the top left of the screen and it's giving me coordinates like (534, 211) for example.
I would like the origin to be at the center of the screen and I would like the very ends of the screen coordinates to be 1.
How can I implement this?
This is the code I got so far...
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
System.out.println(width + " " + height);
mGLView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println(event.getX() + " " + event.getY());
return false;
}
});
Here is an image showing the kind of coordinate system I am trying to implement:
You should get get the coordinates (getX() and getY()) from the MotionEvent and normalize them into the coordinates you want. For example:
#Override
public boolean onTouch(View v, MotionEvent event)
{
float x = 2f * (event.getX() / v.getWidth()) - 1f;
float y = -2f * (event.getY() / v.getHeight()) + 1f;
System.out.println(x + " " + y);
return false;
}
(This assumes that you want your coordinate system relative to the view itself -- in your code you also query the display's dimensions, but I'm not sure why).
In general you can map a point from any range to any range using the following function:
For your case: toRange is (-1,1) and fromRange is (0,width) and (0,height)
double map(double input,double toMin, double toMax,
double fromMin, double fromMax){
return ((input - fromMin)/(fromMax - fromMin)) * (toMax - toMin) +toMin
}
You can then using it as follows:
map(250,-1,1,0,screenWidth)
map(300,-1,1,0,screenHeight)
You can build on top of this function whatever mapping you wish, for example
double center(double input, double maxValue) {
return map(input,-1,1,0,maxValue);
}
Then use it in your code:
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println(center(event.getX(),v.getWidth()) +
" " + center(event.getY(),v.getHeight()));
return false;
}
I'm trying to implement some kind of drag and drop on ImageView. It's working not too bad except one thing :
when I begin to drag object, there is a slight shift on ImageView and I can't resolve this problem.
For example, when I touch the view, I get on logcat :
ACTION_DOWN (margin) : 12x300
then (without moving)
ACTION_MOVE : (margin) 12x245
So the wiew is immediatly redraw and it's not very pretty !
The offset on Y axis between ACTION_DOWN and ACTION_MOVE seems to be depending on bitmap.
Here is my onTouch event code :
the layout left and top margin are set on screen.
public boolean onTouch(View v, MotionEvent event) {
FrameLayout.LayoutParams layout = (LayoutParams) v.getLayoutParams();
if (layout != null){
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d( tag, "ACTION_DOWN (margin) : " + layout.leftMargin + "x" + layout.topMargin);
// finger position on current view
localX = (int) event.getX();
localY = (int) event.getY();
// initial position
parentX = (int) event.getRawX();
parentY = (int) event.getRawY();
v.bringToFront();
Log.d(tag, "ACTION_DOWN : Local " + localX + "x" + localY);
Log.d(tag, "ACTION_DOWN : Raw " + parentX + "x" + parentY);
}
else if (event.getAction() == MotionEvent.ACTION_MOVE) {
// move current view on screen
layout.leftMargin = (int) event.getRawX() - localX;
layout.topMargin = (int) event.getRawY() - localY;
Log.d(tag, "ACTION_MOVE : (margin) " + layout.leftMargin+ "x" + layout.topMargin);
v.setLayoutParams(layout);
}
}
return true;
}
Is anybody can pointed me what i am doing wrong ?
Thanks.
I had a problem, which seems a bit similar. I solved it by setting gravity on the imageView's layoutParams to Gravity.NO_GRAVITY.
I am trying to drag and drop a crosshair onto a MapView. I have an ImageView button on the screen. When I touch it, the button disappears and a new ImageView appears. The new ImageView is supposed to sit centered under my finger until I release it somewhere, but for some reason the offset is incorrect. The crosshair appears down-right of where I am touching.
The image does move proportionately so I believe the problem is with the offset_x and offset_y which I define in the ACTION_DOWN section. Then, in ACTION_UP I need to createMarker(x,y) on the correct coordinates under my finger, but that is offset incorrectly as well.
I have tried various ways to make it centered, and some are better than others. I have so far been unable to make it work without using magic numbers.
As it is, I am using the click location and subtracting half the picture size. This makes sense to me. It's closer to correct if I subtract the whole picture size. I have tried various examples from the web, all of them suffer from inaccuracies with the View location.
Can you give me some advice?
crosshair = (ImageView)findViewById(R.id.crosshair);
frameLayout = (FrameLayout)findViewById(R.id.mapframe);
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
crosshairImage = BitmapFactory.decodeResource(getResources(), R.drawable.crosshair);
crosshair.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
dragStatus = START_DRAGGING;
// hide the button and grab a mobile crosshair
v.setVisibility(View.INVISIBLE);
image = new ImageView(getBaseContext());
image.setImageBitmap(crosshairImage);
// set the image offsets to center the crosshair under my touch
offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ;
offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ;
// set the image location on the screen using padding
image.setPadding(offset_x, offset_y, 0, 0);
// add it to the screen so it shows up
frameLayout.addView(image, params);
frameLayout.invalidate();
if(LOG_V) Log.v(TAG, "Pressed Crosshair");
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if(dragStatus == START_DRAGGING) {
dragStatus = STOP_DRAGGING;
// place a marker on this spot
makeMarker((int)event.getX() + offset_x, (int)event.getY() + offset_y);
// make the button visible again
v.setVisibility(View.VISIBLE);
// remove the mobile crosshair
frameLayout.removeView(image);
if(LOG_V) Log.v(TAG, "Dropped Crosshair");
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (dragStatus == START_DRAGGING) {
// compute how far it has moved from 'start' offset
int x = (int)event.getX() + offset_x;
int y = (int)event.getY() + offset_y;
// check that it's in bounds
int w = getWindowManager().getDefaultDisplay().getWidth();
int h = getWindowManager().getDefaultDisplay().getHeight();
if(x > w)
x = w;
if(y > h)
y = h;
// set the padding to change the image loc
image.setPadding(x, y, 0 , 0);
// draw it
image.invalidate();
frameLayout.requestLayout();
if(LOG_V) Log.v(TAG, "(" + offset_x + ", " + offset_y + ")");
return true;
}
}
return false;
}
});
You have written this code within touch_Down.
offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ;
offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ;
// set the image location on the screen using padding
image.setPadding(offset_x, offset_y, 0, 0);
Try writing it outside the if conditions, just to make sure, it is applied to all the touch events.
You can use new api available in drag and drop
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(null, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}