I'm implementing Drag Drop of one text view to other text view. I've created OnTouchListener and applied on my both TextViews
I wrote OnTouch Function like this
public boolean onTouch(View v, MotionEvent e)
{
switch(e.getAction())
{
case MotionEvent.ACTION_DOWN:
Log.d("Down",v.getId()+"");
break;
case MotionEvent.ACTION_MOVE:
Log.d("Move",v.getId()+"");
break;
case MotionEvent.ACTION_UP:
Log.d("Up",v.getId()+"");
break;
}
return false;
}
I'm facing a problem in all three cases it returns me ID of the TextView on which first time the touch event is fired. I want to obtain the IDs of other TextViews
For example it just give me ID of Down Event "tv1". And again gives me "tv1" on Move Event and Up Event (despite of my position is changed to other TextView whose ID is tv2)
How can i get the ID of TextView on which Touch Up Event has occurred
Logically you should not expect up event of tv2 . because touchListener will listen once you will touch that view, then repeatedly call until up event occurs .
so in my understanding , handle tv2 touch by calculate x,y coordinates in the only way
Related
Im trying to play around with some multitouch in Android.
I have two RelativeLayout on screen where I would like to get touch events.
fooLayout = (RelativeLayout)findViewById(R.id.foo);
fooLayout.setOnTouchListener(onTouchListener);
barLayout = (RelativeLayout)findViewById(R.id.bar);
barLayout.setOnTouchListener(onTouchListener);
...
View.OnTouchListener onTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
...
I tried having a OnTouchListener for each layout but that didn't seem to work at all.
I figured since the onTouch method gets an View I would be able to make out with view the current touch event came from and save away the pointer id.
int pointerId = event.getPointerId(event.getActionIndex());
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
switch (v.getId()) {
case R.id.foo:
fooPointerId = pointerId;
break;
case R.id.bar:
barPointerId = pointerId;
break;
}
This does not work as I thought it would.
When my first finger touches in one of the layouts I will get the correct id from that layout. But when I put down a second finger in the other layout it will get the id of the layout where I put down my first finger.
Am I going about this the wrong way?
Is this possible to do or do I have to put the OnTouchListener on the top view and figure out which layout Im touching by the x/y values of the event?
I think you should extend relative layout and implement onTouchEvent(MotionEvent ev) over there to figure out which pointers are touching which child views(Put foo and bar inside your main relative layout/view group that implements onTouchEvent).
IMO onTouch(View v, MotionEvent ev) only lets you register one pointer at a time so it may not be possible using this approach. This link might help out
I am having trouble detecting the MotionEvent.ACTION_MOVE & MotionEvent.ACTION_UP events. I am intending to have a button when you press and hold, it automatically decreases an associated value, however I have not gotten to that point in coding because I cannot detect the UP event.
for (int position = 0; position < mListItems.size(); position++) {
LayoutInflater inflater = getLayoutInflater();
PilotSkillRow row = (PilotSkillRow) inflater.inflate(R.layout.pilotskillrow, mSkillListView, false);
Button skillminus = (Button) row.findViewById(R.id.skillminus);
skillminus.setOnTouchListener(new SkillButtonTouchListener(position, false));
....
}
I understand returning true on the on touch events means that the later ontouch events such as ACTION_MOVE and ACTION_UP should fire.
private class SkillButtonTouchListener implements OnTouchListener {
public SkillButtonTouchListener(int pos, boolean plus) {
...
}
public boolean onTouch(View view, MotionEvent motionevent) {
int action = motionevent.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_MOVE:
Log.e("a", "MOVE EVENT");
....
return true;
case MotionEvent.ACTION_UP:
Log.e("a", "UP EVENT");
....
break;
case MotionEvent.ACTION_DOWN:
Log.e("a", "DOWN EVENT");
....
return true;
default:
break;
}
return false;
}
}
However, when I run the code, the DOWN even it displayed, but the MOVE and UP EVENTS simply are never displayed. Could it be related to the fact I have an inflated layout?
Anyone have any ideas what I am doing wrong?
Update: If I use the android debugger to connect to the button to check what is happening, the UP event fires when I step through after pressing the button. Probably because there is another process consuming the UP event?
Update 2: The problem is that the textview inside an inflated layout refuses to update. When I perform an invalidate event on the adapter, it will stop the currently processing touch events (no errors). I have another textview which I am able to manually update without the need of the adapter and this does not cause any problems. So it seems to be a problem specific towards RelativeLayout. I have a workaround to only invalidate the data during the ACTION_UP event but I'd rather update the textview on the fly.
I'm using onTouchListener to change the background color when the user's finger is down and change back to default when the user's finger is up. The problem is that when the user's finger is down the background color changes but if the user doesn't takes the finger up and starts scrolling the background color doesn't change to default. Please help.
Below is my code:
V.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
V.setBackgroundColor(Color.BLUE);
break;
case MotionEvent.ACTION_UP:
V.setBackgroundColor(Color.BLACK);
break;
}
return true;
}
});
I've also tried to return false but the result is the same
There are a few different approaches you can use. You can look at MotionEvent.ACTION_MOVE and act when you receive that in your onTouch. You can look at MotionEvent.ACTION_OUTSIDE
and see if they have left the region your are checking.
You can also put a listener on your scroll View and change the background when it moves. Synchronise ScrollView scroll positions - android
Alternately, you could use a gestureListener and detect that.
I got a custom ListView which I fill with an Adaptar. During my application the items within the list will change according to their status so I'm updating my ImageViews like so:
mStatusIcon = (ImageView) findViewById(R.id.imgStatusIcon);
mStatusIcon.setImageResource(R.drawable.icon_cancel);
So far so good. The problem is that I want some kind of focus/hover state on a certain part of my layout. I've set up an OnTouchListener() on my View mHitfield in my layout xml.
I can catch all the relevant actions: ACTION_MOVE, ACTION_DOWN, ACTION_UP and ACTION_CANCEL.
The problem is that when I change my ImageView mStatusIcon the next action I catch is always ACTION_CANCEL.
View mHitfield = (View) findViewById(R.id.outerShape);
mHitfield.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
int currentAction = event.getAction();
switch(currentAction)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// if I comment out these lines I keep receiving all actions
// if I don't, I only receive ACTION_DOWN followed by ACTION_CANCEL
mStatusIcon.setImageResource(R.drawable.icon_download_normal);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// if I comment out these lines I keep receiving all actions
// if I don't, I only receive ACTION_DOWN followed by ACTION_CANCEL
mStatusIcon.setImageResource(R.drawable.icon_download_hover);
break;
}
return false;
}
});
Can somebody explain to me why this is happening and if there is a way to work arround this?
I'm still not really sure why it happened but it was seems the TouchEvent was canceled because the layout was updated within the custom View created. Once I didn't use a custom View but created a XML Layout instead the problem ceased to exist.
Application have a GridView with a images. When user press image - looped sound start playing. When user releases image - sound must stop playing.
I cannot find the way to handle release event.
write touch event in getview method of adapter class. it will work.
public boolean onTouch(View arg0, MotionEvent e) {
switch(e.getAction()){
case(MotionEvent.ACTION_DOWN):
//the user put his finger down on screen
break;
case(MotionEvent.ACTION_MOVE):
//the user is moving with his finger down
break;
case(MotionEvent.ACTION_UP):
//the users finger is off the screen
break;
}
}