Find distance between touch and textview in android - java

I am designing an android app, and one thing I would like to happen is when the user clicks the page, I would like to find the distance between where they clicked and a TextView element on the page. So far, what I have done is set the TextView ID by using
android:id="#+id/TableLayout01"
I know I also need to use android:onTouch coordinates somehow, but I am not sure how to incorporate this into the coordinates of my TextView
Thanks

You can put a touch listener on the whole activity and calculate the distance like this.
public void onCreate() {
setContentView(R.layout.somelayout);
...
TextView textView = findViewById(R.id.TableLayout01);
View mainView = getWindow().getDecorView().findViewById(android.R.id.content);
mainView.setonTouchListener(new View.onTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int rawX = event.getRawX();
int rawY = event.getRawY();
int location[] = new int[2];
textView.getLocationOnScreen(location);
int distanceX = location[0] - rawX;
int distanceY = location[1] - rawY;
// Do something with the distance.
return false;
}
}
...
}

Related

How to get pixel color in a TileView

I have imported a external library to implement a TileView from this library: TileView 2.2.7
I have read all the documentation but I didn't find a method to get the color of the pixel of the touched point.
This is a part of my code, but I think that is not helpful to solve the problem.
public class GetDamages extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TileView tileView = new TileView(getApplicationContext());
tileView.setSize(1855, 2880);
tileView.setScaleLimits(0, 2);
tileView.setShouldRenderWhilePanning(true);
tileView.addDetailLevel(0.125f, "tiles/auto/125/%d_%d.jpg");
tileView.addDetailLevel(0.250f, "tiles/auto/250/%d_%d.jpg");
tileView.addDetailLevel(0.500f, "tiles/auto/500/%d_%d.jpg");
tileView.addDetailLevel(1.000f, "tiles/auto/1000/%d_%d.jpg");
//Setup OnTouchListener
tileView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int eventAction = motionEvent.getAction();
switch (eventAction) {
case MotionEvent.ACTION_DOWN:
double x = tileView.getCoordinateTranslater().translateAndScaleAbsoluteToRelativeX(tileView.getScrollX() + motionEvent.getX(), tileView.getScale());
double y = tileView.getCoordinateTranslater().translateAndScaleAbsoluteToRelativeY(tileView.getScrollY() + motionEvent.getY(), tileView.getScale());
//HERE I NEED TO GET THE PIXEL COLOR
//addPin(tileView, x, y);
break;
}
return false;
}
});
tileView.defineBounds(0, 0, 1, 1);
tileView.setMarkerAnchorPoints(-0.5f, -1.0f);
tileView.setScale(0.5f);
setContentView(tileView);
}
//Add marker in the map
private void addPin(TileView tileView, double x, double y) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.push_pin);
tileView.addMarker(imageView, x, y, -0.5f, -1.0f);
}
}
I have already tried different solution among which this, but
final Bitmap bitmap = ((BitmapDrawable)tileView.getDrawable()).getBitmap();
because TileView doesn't have getDrawable()...
tileView.getTileCanvasViewGroup().setDrawingCacheEnabled(true);
Bitmap hotspots = Bitmap.createBitmap(tileView.getTileCanvasViewGroup().getDrawingCache());
int touchColor;
if (hotspots == null) {
touchColor = 0;
} else { tileView.getTileCanvasViewGroup().setDrawingCacheEnabled(false);
touchColor = hotspots.getPixel((int)x, (int)y);
}
Log.wtf("Debug", "Pixel Color " + touchColor);
This solution return always the same negative integer
Try tileview.tilemap It's just an idea, but it looks like your trying to reference a piece of a map from a view and not the map itself.
BTW, if you are making a game, I would suggest libgdx. It's has a tile map loader built in and a whole game framework. It's also multiplatform.
https://libgdx.badlogicgames.com/
Yes, and you are making map out of this? Because you may just want to use a tiled map loader.
But anyway, looks like tile map canvas has something to do with bitmap rendering, have you looked at that?
http://moagrius.github.io/TileView/index.html?com/qozix/tileview/TileView.html

Google Maps API. Projection

I'm trying to drag ImageView to google map and drop it as a marker.
Map is in FrameLayout:
<FrameLayout
android:id="#+id/map_frg"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
I've set to this FrameLayout OnDragListener:
private class PinDragListener implements View.OnDragListener {
private GoogleMap map;
public PinDragListener(GoogleMap map) {
this.map = map;
}
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
MarkerOptions markerOptions = new MarkerOptions()
.draggable(true)
.anchor(0.0f, 1.0f);
int[] coords = new int[2];
v.getLocationOnScreen(coords);
Projection projection = map.getProjection();
LatLng latLng = projection.fromScreenLocation(new Point(coords[0], coords[1]));
markerOptions.position(latLng);
markerOptions.visible(true);
map.addMarker(markerOptions);
break;
default:
break;
}
return true;
}
}
But when image was dropped somewhere marker placed in the left corner again and again. What can be wrong?
UPDATE:
I've passed dragged view via listener
private class PinTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(data, shadowBuilder, v, 0);
dragPinListener.onViewTouched(v);
return true;
} else {
return false;
}
}
}
and I've got such coordinates every time I dropped marker
x = 0 | y = 1234
Lat = 65.96291676309829 | Lng = -18.548969998955727
The OnDragListener.onDrag() method will get called for each specific event that occurs during the drag-and-drag process, passing in a DragEvent to describe the specifics of each event.
Each DragEvent will have one of the following actions:
ACTION_DRAG_LOCATION : Sent to a view between ACTION_DRAG_ENTERED and ACTION_DRAG_EXITED with the current location of the drag inside that view.
・ The location can be obtained with getX() and getY().
How It Works
Here are example of the drag-and-drop functionality, We have created a custom ImageView that implements the OnDragListener interface.
Please refer to the following this link:
http://www.tutorialspoint.com/android/android_drag_and_drop.htm
https://github.com/wada811/Android-View-Drag-And-Drop-Sample/blob/master/app/src/main/java/com/wada811/android_view_drag_and_drop_sample/DragAndDropFrameLayout.java
Hope it helps.
I need to use event.getX() and event.getY() in onDrag method in OnDragListener to retrieve current view screen location.

Android: Drag and drop button (button disappears; position of the button)

I’m working on an app in which I want to drag a button. I have written two programs. The problem is that each of them is fulfilling only a specific part of what I want. I want a button which can be moved freely on the screen (no disappearing and stuff) and I also need the program to give me the coordinates of the local button position while moving (permanent).
In the first program is the problem that the button disappears while dragging. This happens for the negative values of x and y and also for positive x values (not for positive y values; here is everything perfect). Positive y values are everything above the button, positive x values everything on the right side of the button and so on. For the negative values the button disappears like there is wall which covers the button. For the positive x values the button vanishes with rising x value (a little bit like a fizzing tablet in water).
Here is the code:
seat_leftright = (ImageButton) findViewById(R.id.seat_leftright);
seat_leftright.setOnTouchListener(new OnTouchListener() {
int k = 0;
int prevX,prevY;
int x=0;
int y=0;
#Override
public boolean onTouch(final View v,final MotionEvent event)
{
final LinearLayout.LayoutParams par=(LinearLayout.LayoutParams)v.getLayoutParams();
switch(event.getAction())
{
case MotionEvent.ACTION_MOVE:
{
if(k == 0){ //otherwise there would be an offset when touching the button the first time
prevY=(int)event.getRawY();
prevX=(int)event.getRawX();
}
y+=prevY -(int)event.getRawY();
prevY=(int)event.getRawY();
par.bottomMargin = y;
x+=(int)event.getRawX()-prevX;
prevX=(int)event.getRawX();
par.leftMargin = x;
Log.i("LOG","x: "+ x +", y: " + y );
k++;
v.setLayoutParams(par);
return true;
}
case MotionEvent.ACTION_UP:
{
par.bottomMargin=0;
par.leftMargin=0;
k=0;
y=0;
x=0;
v.setLayoutParams(par);
return true;
}
}
return false;
}
});
}
In the second program I used the DragShadowBuilder function. The button works perfectly in this program, so it is not disappearing or the like. Here I have problems with receiving the values. I constantly need the x and y position of the button while moving. I tried it with the Action_drag_location, but it only returns the coordinates when I’m dragging the button above another button (here it is the button “arrow_down”). Replacing the “arrow_down” button with my background for constantly receiving the coordinates didn’t work at all. I also tried to combine my first program with the second with the result that I didn’t received any values at all.
I hope you can help me with this. I’m grateful for every kind of help!
Below the code of the second program.
OnTouchListener myOnTouchListener = new OnTouchListener() {
#Override
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;
}
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
view.setVisibility(View.VISIBLE);}
return true;
}
};
OnDragListener myDragListener = new OnDragListener() {
#Override
public boolean onDrag(View layoutview, DragEvent dragevent) {
int action = dragevent.getAction();
View view = (View) dragevent.getLocalState();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
Log.i("LOG","DragStarted");
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_LOCATION:
float x = (int)layoutview.getX();
float y = (int)layoutview.getY();
Log.i("COORDS","X: " + x +" Y: " + y);
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.d("LOG", "Drag ended");
if (dropEventNotHandled(dragevent)) {
view.setVisibility(View.VISIBLE);
}
break;
default:
break;
}
return true;
}
private boolean dropEventNotHandled(DragEvent dragEvent) {
return !dragEvent.getResult();
}
};
findViewById(R.id.arrow_up).setOnTouchListener(myOnTouchListener);
findViewById(R.id.arrow_down).setOnDragListener(myDragListener);
#Jay: Thanks for your help, but that didn't solve the problem. The disappearing buttons were due to my layout, where I had this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/seat" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="20dp"
android:layout_marginBottom="160dp"
android:orientation="vertical" >
<ImageButton
android:id="#+id/seat_updown"
android:layout_width="120dp"
android:layout_height="140dp"
android:scaleType="fitCenter"
android:src="#drawable/doublearrow"
android:rotation="90" /> />
</LinearLayout>
Because the ImageButton was imbedded in the LinearLayout it disappeared!
For button drag & drop I share my code here check it.
Here button touch listener.
MultiTouchListener touchListener = new MultiTouchListener(this);
onButton.setOnTouchListener(touchListener);
Touch listener class.
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) {
float currX, currY;
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN: {
mPrevX = event.getX();
mPrevY = event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
currX = event.getRawX();
currY = event.getRawY();
MarginLayoutParams marginParams = new MarginLayoutParams(
view.getLayoutParams());
marginParams.setMargins((int) (currX - mPrevX),
(int) (currY - mPrevY), 0, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
marginParams);
view.setLayoutParams(layoutParams);
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
Sure, you can get these, make sure the views are drawn atleast once before you try to get the positions. You could try to get the positions in onResume() and try these functions
view.getLocationInWindow() or view.getLocationOnScreen()
or if you need something relative to the parent, use
view.getLeft(), view.getTop()
Follow this link for coordinates.
Retrieve the X & Y coordinates of a button in android?

Using android slidingmenu lib with selector

I've been trying to use selectors in slidingmenu for 2 days without managing to make it work.
Here is what I want to do :
I've a menu which have a ListView in it. I want the selector to point at one particular item and move with the item when the listview is scrolled.
So basically the selector is pointing at the right item but when I'm scrolling, the selector don't move on my phone (android 4.0.4) but it work with the emulator (4.1.2). Do you have any idea of why the menu is not invalidating itself when I ask him to do so ?
/*Setting the sliding menu */
setBehindContentView(R.layout.menu);
setSlidingActionBarEnabled(true);
getSlidingMenu().setMode(SlidingMenu.LEFT);
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
getSlidingMenu().setFadeEnabled(true);
getSlidingMenu().setFadeDegree(0.35f);
getSlidingMenu().setShadowWidth(15);
getSlidingMenu().setShadowDrawable(R.drawable.shadow);
getSlidingMenu().setSelectorEnabled(true);
getSlidingMenu().setSelectorDrawable(R.drawable.selector);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
getSlidingMenu().setBehindWidth((int) (metrics.widthPixels * 0.8));
getSlidingMenu().setSelectedView(null);
/*Creating the content of the sliding menu*/
/*Now we generate the menu below */
maListViewPerso = (ListView) this.findViewById(R.id.listviewperso);
maListViewPerso = SlidingMenuListCreator.getListView(this, (String) this.getTitle(), maListViewPerso, isMissionSelected, isTourneeOpened);
getSlidingMenu().setOnOpenListener(new OnOpenListener() {
#Override
public void onOpen() {
int wantedPosition = 5; // Whatever position you're looking for
int firstPosition = maListViewPerso.getFirstVisiblePosition() - maListViewPerso.getHeaderViewsCount(); int wantedChild = wantedPosition - firstPosition;
if (wantedChild < 0 || wantedChild >= maListViewPerso.getChildCount()) {
} else {
selectedView = maListViewPerso.getChildAt(wantedChild);
}
getSlidingMenu().setSelectedView(selectedView);
getSlidingMenu().invalidate();
}
});
OnTouchListener mOnTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
maListViewPerso.onTouchEvent(event);
int wantedPosition = 5; int firstPosition = maListViewPerso.getFirstVisiblePosition() - maListViewPerso.getHeaderViewsCount(); int wantedChild = wantedPosition - firstPosition;
if (wantedChild < 0 || wantedChild >= maListViewPerso.getChildCount()) {
} else {
selectedView = maListViewPerso.getChildAt(wantedChild); }
getSlidingMenu().setSelectedView(selectedView);
getSlidingMenu().getmViewBehind().invalidate();
return true;
}
};
maListViewPerso.setOnTouchListener(mOnTouchListener);
After all I never find the solution.
But :
I switched to a viewpager navigation mode because that what was users preferred (and discovered that, yes, Fragments are awesome)
Google have finally made this navigation pattern "official" by adding it through the support library and drawerlayout and it works very well for me =)

ImageView getLocationtOnScreen android

I am trying to get the coordinates of the image on the screen. I currently have an ImageView within an activity. I understand that the getLocationOnScreen() method can only be called once the layout has been created, so calling this method within the oncreate function would return [0,0]. But I do not know how to get this method to return the correct values. I have tried overiding various superclass methods, like the onstart method or the onTouchEvent method and it still returns [0,0] to me. The code I currently have is as follows:
#Override
public void onCreate(Bundle savedInstanceState)
{
// Some code here after which ..
image = (ImageView) findViewById(R.id.imageVfi);
image.setImageBitmap(imageData.entrySet().iterator().next().getValue());
}
Then I have the onStart method which I have overriden
#Override
public void onStart()
{
super.onStart();
image.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int[] dim = new int[2];
image.getLocationOnScreen(dim);
new AlertDialog.Builder(DisplayPicture.this)
.setIcon(R.drawable.icon)
.setTitle("Touch coordinates : " +
String.valueOf(dim[0]) + "x" + String.valueOf(dim[1]))
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
}
}).show();
// image calculations go here
return true;
}
});
}
This returns 0X0 to me. Any help is much appreciated.
ImageView does not offer a way to get the location of its image on screen. You can only query the location of the ImageView itself. You can try to use ImageView.getImageMatrix() but I'm not sure we populate it when the image is simply centered (as opposed to scaled, etc.)
Solution after following advice given above
Solution:
Following the advice provided by Romain Guy below, I was able to get the co-ordinates but adding the following code to the onStart overidden method.
display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getOrientation();
float rowStart=0, rowEnd=0, columnStart=0, columnEnd=0;
if(orientation ==0)
{
final Matrix matrix = image.getImageMatrix();
float[] values = new float[9];
matrix.getValues(values);
rowStart = values[0];
columnStart = values[5];
rowEnd = image.getWidth()-rowStart;
columnEnd = image.getHeight()-columnStart;
}else if(orientation == 1)
{
final Matrix matrix = image.getImageMatrix();
float[] values = new float[9];
matrix.getValues(values);
rowStart = values[2];
columnStart = values[3];
rowEnd = image.getWidth()-rowStart;
columnEnd = image.getHeight()-columnStart;
}
If it's only the image view that you have in your activity, then it will be positioned by default in the top left corner with coordinates 0x0.

Categories