How to detect view has been touched when dragged over from another view
I couldn't find a way to do this through the actual custom views and had to go one layer back.
The position of the views are documented on the FrameLayout that contains each view.
In the FrameLayout, I ended up overwriting onTouchEvent
.
I ended up having to do something similar to this:
@Override
public boolean onTouchEvent(MotionEvent event) {
float xCoord = event.getX();
float yCoord = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Using X and Y coordinates, find out if touch event is on top of a view.
// Mark the view as touched
return true;
case MotionEvent.ACTION_UP:
// Action required once touch released.
return true;
default:
// When dragging, the default case will be called.
// Using X and Y coordinates, figure out if finger goes over a view.
// If you don't want same behaviour when going back to previous view,
// then mark it so you can ignore it if user goes back to previous view.
}
}
Once case MotionEvent.ACTION_UP
gets called, you can use the fact that the views were marked to know which ones were touched. You can also get the order if required by putting the views in an array when marking them.
Detect touch event on a view when dragged over from other view
You can use the code bellow to achive your request:
Method to test view bounds (used in code beloow)
Rect outRect = new Rect();
int[] location = new int[2];
private boolean isViewInBounds(View view, int x, int y){
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
Testing with two TextView
final TextView viewA = (TextView) findViewById(R.id.textView);
final TextView viewB = (TextView) findViewById(R.id.textView2);
Setup viewA
The empty OnClickListener
is required to keep OnTouchListener
active until ACTION_UP
viewA.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
viewA.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
if(event.getAction() == MotionEvent.ACTION_UP){
if(isViewInBounds(viewB, x, y))
viewB.dispatchTouchEvent(event);
else if(isViewInBounds(viewA, x, y)){
Log.d(TAG, "onTouch ViewA");
//Here goes code to execute on onTouch ViewA
}
}
// Further touch is not handled
return false;
}
});
Setup viewB
This is only required if you also want to press on viewB and drag to viewA
viewB.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
viewB.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
if(event.getAction() == MotionEvent.ACTION_UP){
if(isViewInBounds(viewA, x, y))
viewA.dispatchTouchEvent(event);
else if(isViewInBounds(viewB, x, y)){
Log.d(TAG, "onTouch ViewB");
//Here goes code to execute on onTouch ViewB
}
}
// Further touch is not handled
return false;
}
});
Regards.
How to implement detection of a View being dragged over another view?
The animated translation is unnecessary since the touch events should move the TextView smoothly about. Just assign new X,Y coordinates to the TextView, like this:
view.setX(view.getX() + deltaX);
view.setY(view.getY() + deltaY);
Determine which view is currently being Touched while user Moves finger
Found my answer here:
Android : Get view only on which touch was released
Looks like you have to loop through the child views and do hit detection manually to find which view the touch is currently over.
Did this by overriding dispatchTouchEvent on the parent LinearLayout:
LinearLayout parent = new LinearLayout(this.getActivity()){
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = Math.round(ev.getX());
int y = Math.round(ev.getY());
for (int i=0; i<getChildCount(); i++){
LinearLayout child = (LinearLayout)row.getChildAt(i);
if(x > child.getLeft() && x < child.getRight() && y > child.getTop() && y < child.getBottom()){
//touch is within this child
if(ev.getAction() == MotionEvent.ACTION_UP){
//touch has ended
}
}
}
return true;
}
}
Related Topics
How to Parse This Nested JSON Array in Android
Passing Strings Between Activities in Android
How to Change the Color of a Switchcompat from Appcompat Library
Android Volley + JSONobjectrequest Caching
How to Share a Single Library Source Across Multiple Projects
Android Webview with Garbled Utf-8 Characters
Programmatically Change Input Type of the Edittext from Password to Normal & Vice Versa
How to Style the Standard React-Native Android Picker
Gradle Dsl Method Not Found: 'Compile()'
How to Apply Zoom, Drag and Rotation to an Image in Android
When to Clear the Cache Dir in Android
Android:Actionbarstyle Requires API Level 11
Update Listview Dynamically with Adapter
Android: Remove All the Previous Activities from the Back Stack
How to Get Screen Coordinates from Marker in Google Maps V2 Android