I am using table layout to display data, but i want it to behave like list items
(ability to select, when select change background, when click, having hover effect, click able) for that purpose i am using following listeners
OnClickListener(to perform action)
OnFocusChangeListener(To change background color)
OnTouchListener(to focus specific row)
Now problem is when user touch any item it get focus first and then have to touch again to fire onclick event, to fix this i made a change and ontouch i fire action on specific to row.
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_UP){
v.requestFocus();
int viewId= v.getId();
handleEvent(viewId);//Switch cases to perform row specific actions.
}
return false;
}
now if user touch the row event get fired that works perfect, But one more problem rises here when even user want to scroll down the data via dragging finger onto the screen ontouch event get fired.... and action automatically performed although user think it will scroll down the screen.
I don't know if this solution is applicable in your case, but maybe you can do like this:
Let's assume that user clicked your item (so probably you will get sequence of three events to your OnTouch() method: ACTION_ DOWN, ACTION_ MOVE (not necessarily) and ACTION_UP. Now you can react accordingly.
If it's ACTION_DOWN, you can save x and y coordinates.
If it's ACTION_ MOVE, take its x and y and calculate the distance from corresponding ACTION_DOWN. If it's longer than some assumed value, then make the scroll and set the flag indicating that items were scrolled.
If it's ACTION_UP check your flag. If items were not scrolled, fire your action and clear the flag.
Probably calculations is not what you should do in ACTION_MOVE event, because it should be fast, but give it a try.
Regards!
Related
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.
I've got a big headache and spent a few hours to solve my problem withou any reasonable results.
I use a custom adapter (extending ArrayAdapter) to show listview items. This adapter implements OnTouchListener. There's also a background selector which color is changing when an item is touched and OnItemClickListener in ListViewActivity.
What I need is capture touch events (all of them, not only ACTION_DOWN) in the adapter. When onTouch returns false, the consecutive events (ACTION_CANCEL, ACTION_UP etc.) aren't captured. On the other hand returning true stops dispatching all other events (e.g. click) so that the ListViewActivity's onItemClick is never triggered.
I tried hard to find any working solution in SO and other resources, but with no success.
One idea was not worry about click events and background. I may set the background programatically and trigger click event the same way when the onTouch action is ACTION_UP, but view.performClick() does nothing (view is the 1st argument of onTouch method).
[EDIT]
To make it clear, I want to handle touch events in the adapter beacuse I need the textview in the item to marquee when the user touches it. Thus, in onTouch, when the action equals ACTION_DOWN, I assign true to setSelected property of the textview and, consequently, false when ACTION_CANCEL or ACTION_UP.
Any suggestions?
Thanks in advance.
I have a tablet app with a Master / Detail layout, with a TableView in the Master panel that changes the content of the Detail pane. I'd like to have the master's row stay highlighted when clicked like it does in the android OS settings.
Right now the best I'm able to do is set the backgroundColor to a new color in response to a 'click' event. However, when I do a quick tap, the row highlights, then blinks back to normal before highlighting again. I'm guessing this is the delay between when I lift my finger off and when the backgroundColor gets changed.
tableview.addEventListener('click', function(e) {
...
else if (e.rowData.id == 3) { // scan history
e.row.backgroundColor = 'blue';
This appears to be the way others have done it: http://developer.appcelerator.com/question/124359/android---tableviews-deselectrow
And if I was just using android and not Titanium: How can I highlight the table row on click ?
Try this instead. The touch start is called immediately, while the click usually is not. Note that according to the docs a scroll event and a touch event cant happen concurrently for iOS and Android, so you probably want to handle the touchcancel event also if you have a `touchstart`` listener.
tableview.addEventListener('touchstart', function(e) {
...
// Get the source row, and then get its id
else if (e.source.id == 3) { // scan history
e.row.backgroundColor = 'blue';
});
EDIT:
Maybe a better way to do this would be to handle the touchend event. This would handle bothe the quick taps, the user sliding to a different row, and the scrolling edge cases.
When creating your row, use:
selectionStyle : "NONE"
This prevents it from changing color on click/touch
And roll your own event listeners to govern exactly when your row is highlighted.
The iOS blue row selection color is something like: "#006EF1"
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?