OnTouch event on Screen - android

I have xml in which I have 2 relative layouts, the first one is map(using map fragments) and the second one is ViewPager layout. I added button to map to hide map when clicked, now I want a method to get back the map layout by sweep down the screen.
I tried setting onTouchListener to relative layout but it is not working, also tried implementing OnTouchListener
public class MainActivity extends FragmentActivity implements OnTouchListener
it is not working! how to achieve this?
#Override
public boolean onTouch(View v, MotionEvent event) {
x= event.getX();
y=event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
sX = event.getX();
sY = event.getY();
break;
case MotionEvent.ACTION_UP:
fX = event.getX();
fY = event.getY();
if(fX-sX == 0 || fX-sX > 0 || fX-sX <0)
if(fY-sY < 0)
{
if(mapview.getVisibility()==View.GONE)
{
mapview.setVisibility(View.VISIBLE);
}
}
break;
}
return true;
}

Post your code, btw in simple way, ACTION_DOWN is when you touch the screen, ACTION_UP is when you finger release the screen. Look here

Related

Edittext not editable after dragged

I have added drag functinality to my custom editext by overriding the touchevent()
Now the problem is after the edittext is dragged and dropped in a particular position and i want to input text into the edittext by clicking on it, it still getting dragged maybe because the touch event has been overriden and keyboard does not appear to input text
The workaround maybe triggering the dragfunctionality on long press but now the default longpress functionality of the edittext may change
I dont want this to happen
What to do.
mainactivity.java
public class MainActivity extends Activity
{
RelativeLayout dropLayout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dropLayout = (RelativeLayout) findViewById(R.id.ondraglayout);
dropLayout.setOnDragListener(new MyDragListener());
EditText et = (EditText) findViewById(R.id.mainEditText1);
}
}
my customedittext.java
public class CustomEdittext extends EditText
{
public CustomEdittext(Context context){
super(context);
}
public CustomEdittext(Context context, AttributeSet attr){
super(context, attr);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
switch(event.getAction()){
case MotionEvent.ACTION_DOWN :
break;
case MotionEvent.ACTION_MOVE :
ClipData dragdata = ClipData.newPlainText("","");
View.DragShadowBuilder shdwbldr = new View.DragShadowBuilder(this);
this.startDrag(dragdata, shdwbldr, this, 0);
this.setVisibility(View.INVISIBLE);
break;
}
return true;
}
}
mydraglistener.java
public class MyDragListener implements OnDragListener
{
private RelativeLayout.LayoutParams params;
#Override
public boolean onDrag(View v, DragEvent event)
{
View view = (View) event.getLocalState();
switch(event.getAction())
{
case DragEvent.ACTION_DRAG_STARTED:
params = (RelativeLayout.LayoutParams) view.getLayoutParams();
break;
case DragEvent.ACTION_DRAG_ENTERED:
int x = (int) event.getX();
int y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED :
break;
case DragEvent.ACTION_DRAG_LOCATION :
x= (int) event.getX();
y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED :
break;
case DragEvent.ACTION_DROP:
x = (int) event.getX();
y = (int) event.getY();
params.leftMargin = x;
params.topMargin = y;
view.setLayoutParams(params);
view.setVisibility(View.VISIBLE);
break;
default: break;
}
return true;
}
}
my main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#CDC2C0"
android:id="#+id/ondraglayout">
<com.mycompany.myapp.CustomEdittext
android:layout_height="wrap_content"
android:ems="10"
android:layout_width="wrap_content"
android:id="#+id/mainEditText1"/>
Your whole code not making sense at all: First let discuss what happening inside your onTouchEvent:
#Override
public boolean onTouchEvent(MotionEvent event)
{
switch(event.getAction()){
case MotionEvent.ACTION_DOWN :
break;
case MotionEvent.ACTION_MOVE :
ClipData dragdata = ClipData.newPlainText("","");
View.DragShadowBuilder shdwbldr = new View.DragShadowBuilder(this);
this.startDrag(dragdata, shdwbldr, this, 0);
this.setVisibility(View.INVISIBLE);
break;
}
return true;
When you put your finger in the screen, the system first trigger MotionEvent.ACTION_DOWN, and afterwards, she will deliver events of MotionEvent.ACTION_MOVE as long as nothing else in the system will consume this events. The meaning of this is your call for startDrag() will call on each movement of the finger, not really make sense right? So first I suggest you to move the code from MotionEvent.ACTION_MOVE into MotionEvent.ACTION_DOWN.
Now to the more important part. When you assign a DragListener to View, the meaning is that this View will receive all the DragEvent that the system will deliver as long as the Listener returns true for the DragEvent.ACTION_DRAG_STARTED.
Now, you assigned your DragListener, to the RelativeLayout. So lets look into your code:
case DragEvent.ACTION_DROP:
x = (int) event.getX();
y = (int) event.getY();
params.leftMargin = x;
params.topMargin = y;
view.setLayoutParams(params);
view.setVisibility(View.VISIBLE);
break;
You set new position for the LayoutParams, but who is the View that will receive this params? The RelativeLayout, not your EditText. Actually your EditText is now INVISBLE as you set it visibilty to INVISIBLE inside your onTouchEvent and never changed it back. Your code "view.setVisibility(View.VISIBLE);" inside the ACTION_DROP is not referring to the EditText but to the RelativeLayout. Unless there is other code you not shown here, this is the case.
Anyway, in your case I would recommend you to move your startDrag() call to a LongCLickListener. I have no clue which functionality of the EditText you think that may change ,as, at least as far as I know, there is no functionality for LongClick in EditText. If you want to avoid it you can also add a flag to your code and turn it on after the ACTION_DROP, and then make the code inside the ACTION_DOWN to run just if this flag is set to false.

Drag and drop in ScrollView

I have some ImageViews inside a HorizontalScrollView.
I would like to be able to drag and drop the ImageViews somewhere else, but still maintain scrolling capability. Dragging should only be activated when the user starts a mostly vertical motion with their finger.
For now, I have drag and drop activate on long-press, but that is not a good solution.
To illustrate:
I had to do exactly this as well. After reading http://techin-android.blogspot.in/2011/11/swipe-event-in-android-scrollview.html I adapted the code as follows:
class MyOnTouchListener implements View.OnTouchListener {
static final int MIN_DISTANCE_Y = 40;
private float downY, upY;
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downY = event.getY();
return true;
}
case MotionEvent.ACTION_MOVE: {
upY = event.getY();
float deltaY = downY - upY;
// swipe vertical?
if (Math.abs(deltaY) > MIN_DISTANCE_Y) {
if (deltaY < 0) {
//Start your drag here if appropriate
return true;
}
if (deltaY > 0) {
//Or start your drag here if appropriate
return true;
}
}
}
}
return false;
}
}
And then set the listener on the ImageViews:
imageView.setOnTouchListener(new MyOnTouchListener());
In this version of the code I am only checking for movement in the vertical direction (I also changed the minimum movement to be 40 instead of 100 as in the original code). If a vertical movement is detected, the specific ImageView can begin to drag or do any other actions you want. If a vertical movement is not detected, the ImageView's MyTouchListener returns false which means the ImageView does not consume the touch event. This allows the parent ScrollView to eventually get the touch event and consume it (for scroll detection). The answers here are helpful for understanding touch events: MotionEvent handling in ScrollView in Android.

How do I detect if a user has touched any part of the screen other than the inside of an EditText?

I am guessing this means making the whole screen touchable. How exactly is that done?
and secondly calculating if an X,Y is within the EditText.
override the onTouchEvent in the activity you want to implement this....and get the X, Y co-ordinates using event.getX() and event.getY()
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
return false;
}
but i suggest you must search thoroughly before posting a question.

Correctly detecting a swipe on a GridView placed inside a ViewPager in Android

I have a ViewPager which uses GridViews for pages. I would like the ViewPager to switch pages when I swipe across the screen.
The problem is that swipes are not detected when they are made across the GridView. Outside of the GridView, the swipes work correctly; it seems that the GridView is trapping all touch events without passing it to ViewPager first.
While fiddling with the source code, I did this to a custom class extended from GridView:
#Override
public boolean onTouchEvent(MotionEvent event) {
return pager.onInterceptTouchEvent(event);
}
-- where pager refers to the ViewPager class. With this, ViewPager will correctly detect swipes and move pages accordingly, but it doesn't allow GridView to accept any events, so I can't click on the items.
What I would like to be able to do is correctly detect swipes in ViewPager and item clicks on GridView.
I had trouble with colig's implementation, but I was able to get it to work by subclassing ViewPager and overriding the onInterceptTouchEvent() method. I only checked for swipes in the X direction to allow for vertical scrolling if necessary.
private static final int minSwipeDistance = 30;
private float mTouchX;
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean response = super.onInterceptTouchEvent(event);
float x = event.getX();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mTouchX = x;
break;
case MotionEvent.ACTION_MOVE:
float dX = Math.abs(x - mTouchX);
if (dX > minSwipeDistance)
return true;
break;
}
return response;
}
Alix is on the right track. I managed to come up with this simple-looking fix. I'm not entirely sure of how it works, but it does! And for future reference, it works for other kinds of views too -- TableLayout, for example -- not just GridView.
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
downX = x;
downY = y;
return super.onInterceptTouchEvent(event);
}
case MotionEvent.ACTION_MOVE: {
deltaX = Math.abs(downX - x);
deltaY = Math.abs(downY - y);
return super.onTouchEvent(event);
}
case MotionEvent.ACTION_UP: {
if (deltaX > 4 && deltaY > 4) {
super.onTouchEvent(event);
}
}
}
return super.onInterceptTouchEvent(event);
}
You can override onInterceptTouchEvent for dispatch evenement where you want

Android, GridView and onTouchListener

My application have three pages (three tabs) and I want to switch beetween two gridviews by moving finger horizontaly. The touch code works fine but I can't click anymore on the grid items! I use the method onItemClickListener (onClickListener don't works on Gridview) but the grid item is not clicked.
Thanks for your help!
The code is :
myGrid.setOnTouchListener(this);
myGrid.setOnItemClickListener(this);
....
public boolean onTouch(View v, MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
xStart = event.getX();
break;
case MotionEvent.ACTION_UP:
xEnd = event.getX();
if (xEnd - xStart > 20){
//switch to previous tab
}
if (xEnd - xStart < -20){
//switch to next tab
}
return true;
default:
break;
}
return true;
}
What view is that onTouch code in? You could try changing that last return true to return false so that if the action wasn't a motionevent, the event is not consumed by the view.

Categories

Resources