This question is a bit awkward. Is it possible to transfer the touch focus of one view to another? Basically, say that you have a view that picks up the first ACTION_DOWN touch event, and then immediately wants to transfer the focus for all touch events to another view to handle with it's onTouchEvent(MotionEvent event). I thought that doing the following would make it work, but it didn't:
#override
public boolean onTouchEvent(MotionEvent) {
this.clearFocus();
anotherView.setFocusableInTouchMode(true);
anotherView.requestFocus();
}
Obviously, it seems to me that it just doesn't work that way. Could someone explain to me how I can go about doing something like this?
If it's still a bit difficult to understand my question, think about a regular button. When pressed, the button is highlighted (focused) and if you move your finger off the button but still keep your finger on the screen, the button becomes unfocused but still has control of the entire touch events (no other view can become focused even if you move over them). My question asks if it is possible to transfer this touch focus to another view to handle without having you to remove your finger off the screen.
Try below code might work
button1.setOnFocusChangeListener(new OnFocusChangeListener()
{
#Override
public void onFocusChange(View arg0, boolean hasFocus)
{
if(hasFocus)
button2.requestFocus();
}
});
The way I worked around this was to have a single view "harness" whose sole purpose was to pass on the touch information to the other classes, who would then do the processing. Note that ViewA and B don't actually have to be views and extend the view class. Its not an ideal solution, but I don't think it's possible to solve this problem with the current Android framework (ICS/JB).
class ViewHarness extends View{
public boolean onTouch(MotionEvent event){
if(ViewA is selected)
ViewA.onTouch(event);
else
ViewB.onTouch(event);
}
Related
I'm using two different layouts in my activity where in one activity i need to work with touch screen and in another activity it should not work on Touch screen.
How i can do it?
I tried to used dispatchTouchEvent to get the touch response but it gets for the entire activity, is there any way to get based on the layout ?
I used
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
.
.
.
return true;
}
if i used like this it disables all the touch event in my activity.
I have implemented swipe behavior in my list view. So, basically, you can drag a item and item's alpha value would change accordingly (thanks to code by Roman Nurik Roman Nurik & Tim Roes). The application is doing fine. Basically, on a generic list item, touch is treated as click, so for list without dragging facility, do not find difference between the two. But in my case, since I detect the co-ordinate at onTouch() to judge whether the user is scrolling left to right or right to left. My list does makes a difference between touch and click. So, I want to know do I dispatch a click event manually on list item so that even if user has not clicked and has dragged the item on touch, i still get to call OnListItemClick().
Thanks.
Long time, no reply given.
Anyway, I thought to share my own findings on this question.
I found that there is no way of dispataching an event manually as far as I know. But I found that I could handle my problem in another way. Here is how I handled it.
public boolean onTouch(View v, MotionEvent event) {
if(v.isPressed()
//
}
isPressed() would return when view is in pressed state. When it returns true, you can proceed further.
Hope it helps someone else.
in iOS world, there's a concept of touchUpInside, touch started within a view and user lifted a finger within a view bound.
I see touch vs click (event listeners) in android, and I'd like to know the difference between them.
Touch events are much more basic. There's many varieties. The most common being:
DOWN: The user touch the item
MOVE: The user shifts around the item after touching it
UP: The user stops touch the item
CANCEL: The user shifts off the item but is still touching the screen.
In Android, a click event is a composite of touch events. In the case of click it's both DOWN and UP action. There are others that can be found in a GestureDetector. Fling for example is a combination of DOWN, MOVE, and UP in a fast motion that signifies the user swiped the finger really fast.
EDIT:
Clarification on how Android handles the true and false in onTouchEvent().
It's not very well documented, but the way the Views work in Android is that when you touch a View, it will send that touch event from the parent view to all children views. Each child will then send the event to it's children. This is done in the dispatchTouchEvent() method.
When a parent View receives false from the child's onTouchEvent() method, it will no longer send touch events to that child. Meaning that when you're view returns false in onTouchEvent(), your View is really says:
I am done processing touch events and all of my children are done as well.
90% of the time, in onTouchEvent() you would do return super.onTouchEvent() to return the touch values of all the children in the View.
So let's look at your click example. Here's one way to do it in which you return false on a DOWN event, but true on an UP.
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return false;
case MotionEvent.ACTION_UP:
return true;
break;
default:
return false;
}
}
In this case, the parent of this View will receive false immediately. After which, it will stop sending touch events to this View because you said it was done.
Here's another way:
boolean mPossibleClick = false;
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPossibleClick = true;
break;
case MotionEvent.ACTION_UP:
if(mPossibleClick) {
// UP event immediately after DOWN. Perform click action
}
default:
mPossibleClick = false;
}
return mPossibleClick;
}
It's rather crude, but basically here's what will happen. When the user first touches it, you will receive DOWN which will return true. If the user lifts the finger, it will perform a click action after which will return false because the event is done. If the user moves his finger or any other action is performed, it will return false and the click will be nulled out.
That last one is not the best way to implement a click, but I think it illustrates what I'm trying to say. In real life, move events are extremely common if even for a couple pixels.
onClickListener is used whenever a click event for any view is raised, say for example: click event for Button, ImageButton.
onTouchListener is used whenever you want to implement Touch kind of functionality, say for example if you want to get co-ordinates of screen where you touch exactly.
Definitions:
onClickListner: Interface definition for a callback to be invoked when a view is clicked.
onTouchListener: Interface definition for a callback to be invoked when a touch event is dispatched to this view. The callback will be invoked before the touch event is given to the view.
Details:
onClickListener: http://developer.android.com/reference/android/view/View.OnClickListener.html
onTouchListener: http://developer.android.com/reference/android/view/View.OnTouchListener.html
refer to the response of PH7
which one is better to use?
It really depends on your requirement.
onTouch gives you Motion Event. Thus, you can do a lot of fancy things as it help you separate state of movement. Just to name a few
ACTION_UP
ACTION_DOWN
ACTION_MOVE
Those are common actions we usually implement to get desire result such as dragging view on screen.
On the other hand, onClick doesn't give you much except which view user interacts. onClick is a complete event comprising of focusing,pressing and releasing. So, you have little control over it. One side up is it is very simple to implement.
do we need to implement both?
It is not necessary unless you want to mess up with your user. If you just want simple click event, go for onClick. If you want more than click, go for onTouch. Doing both will complicate the process.
From User point of view, it is unnoticeable if you implement onTouch carefully to look like onClick.
for more details : refer this and this
In a ListFragement I want to display additional edit options next to an item after the user long-clicks onto it.
This works fine using the following code in a custom ArrayAdapter (inside getView):
rowView.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
//Show the edit controls
View editArea = rowView.findViewById(R.id.editArea);
editArea.setVisibility(View.VISIBLE);
//Don't raise additional events for this touch
return true;
}
});
However, my problem is which event to use in order to hide those additional edit controls.
Ideally, when the edit controls are displayed, any touch outside them should be ignored in favor of hiding them (a little bit like when a dialog is opened and the user clicks somewhere besides it).
I tried overwriting dispatchTouchEvent in my MainActivity - if I generally intercept all ACTION_DOWN events, however, my edit controls are hidden before the click is dispatched to them (of course).
Is there any possibility to detect which control the user has touched without already dispatching the event?
If I intercept all ACTION_UPs, the edit-controls are removed when the user ends their long-click. And I am trying to avoid whether a specific ACTION_UP belongs to the long touch as this would produce some really messy code.
Any ideas which event to listen to?
Or do you know any better, alternate way to achieve my goal?
I want to create an event to change what my image button looks like, but only when it is being pushed down. So far I have been using an onTouch listener, but that just changes it permanently. I can't find anything like an onKyeUpListener() type of thing for the button.
Does anything like this exist?
SOLVED
final ImageButton button = (ImageButton) findViewById(R.id.ImageButton01);
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == (MotionEvent.ACTION_UP)){
//Do whatever you want after press
}
else{
//Do whatever you want during press
}
return true;
}
});
It's in the docs. You can define different images for different states via XML.
Instead of doing it manually, why don't you change the drawable of your buttons? In general, drawables can have multiple states, so if you change the drawable for certain states (like focused or selected), the operating system will handle everything for you automatically.
From http://developer.android.com/guide/topics/ui/ui-events.html:
onTouch() ... This is called when the user performs an action qualified as a touch event, including a press, a release, or any movement gesture on the screen (within the bounds of the item).
In other words, onTouch is also called for release events. Look at MotionEvent.getAction().