Hello right now I'm developing a custom view where there'll be 2 listview that the header can be stacked each other like this picture :
||
||
\/
I already succeed to create this view, by overriding overscrolled and intercept all touch and playing with the margin of the header contents. but the problem now is because I intercept all touch now I can't tap the content of the listview, I know the flow of the touch is from ACTION_DOWN -> ACTION_MOVE -> ACTION_UP, and then when I dispatch the event to the child the tap is working but the scroll isn't working at all.
So for now the flow for my view is like this onInterceptTouchEvent -> onTouch -> gestureListener (or with overscroll)
this is some part of my code
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
onTouchEvent(ev);
return true;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
topListViewHeight = lvFirstListView.getTotalHeight() - rlFirstHeader.getHeight();
if(isBottomScrollable) {
listGestureDetector.onTouchEvent(event);
lvSecondListView.dispatchTouchEvent(event);
} else {
gestureDetector.onTouchEvent(event);
}
return true;
}
Is there anybody here have an idea about this? Any suggestion is very appreciated and if you need more question about this question please ask me.
Thanks before
Related
I have an activity with an expandableListView in it !
I would like to register to an event when someone clicks on the expandableListView, but not on a group nor an item. In other words, when there is space left under all items, i want to capture a click there.
I tried a lot of things, and the only thing that works for me is
expListView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Toast.makeText(SetsActivity.this, "" + event.getY()), Toast.LENGTH_SHORT).show();
}
return false;
}
});
Unfortunately, this captures everything. I would like to be able to know if this is the empty space or not. Is there a way ?
I am trying to implement UI like google keep.
In the main layout there is frame layout in which there is a FAM(Floating Actions Menu) and a blackshadow view which is visible when FAM is expanded.
What i want is that when i touch the shadow view it should Collapse the FAM. To do that i have implemented onTouchlistner on shadowview.
shadowview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(fam.isExpanded()){
fam.collapse();
}
return false;
}
});
But what happens is that when i touch the area with MyCardGridView's card (Which open's another activity) open's another activity. Which should not happen.
You should try to use return true; instead of return false;, because as the documentation says :
Returns:
True if the listener has consumed the event, false otherwise.
Maybe the issue here is caused by return false
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to implement doubletap on imageview’s onclick?
In my application I have a Relative layout with three image views.
In the activity I have implemented the simplegesturelistener for getting the swipe to work. Because of this i had to override the onDoubleTap method as well.
My problem is that I want to use the double tap event to zoom out the image from the image view on which the double tap happened (Need to recognize one of the three image views on the layout).
Is there a way to achieve this in the current scenario?
You can refer below code
gestureDetector = new GestureDetector(new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
Here I have used Gesture for swipe functionality, and I also have webview in layout in which swipe should work.
So webview's scroll and swipe both should work i have added below methods. Mainly this method is important to add dispatchTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
return (gestureDetector.onTouchEvent(event) || super
.onTouchEvent(event));
}
#Override
public boolean dispatchTouchEvent(MotionEvent e) {
super.dispatchTouchEvent(e);
return gestureDetector.onTouchEvent(e);
}
I am using onTouchListener for a layout. I want to take the click outside the layout. I set onTouchListetener for the layout. But motion event always shows ACTION_DOWN. Even i touchOutside the view, It is not showing ACTION_OUTSIDE. Could anyone help me to find out why it is not showing constant ACTION_OUTSIDE. Here is the code i am using
Layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("action",event.getAction()+"");
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "check", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
If you return false, then you're signifying that you do not wish to receive further touch events. You need to return true to continue getting motion events.
Very simple to fix by adding this:
override fun onTouchEvent(event: MotionEvent): Boolean {
return true
}
The event listener itself listens to one event action at a time. The first of course is the ACTION.DOWN, in which your toast shows.
Just like what Jason Robinson and user936414, you have to return it to true so that the object or the listener could here the second event action, ACTION.OUTSIDE.
You will get ACTION_OUTSIDE when the touch is outside the activity and the flag FLAG_WATCH_OUTSIDE_TOUCH is set. Refer http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_WATCH_OUTSIDE_TOUCH
I have a application that need event handling on a unusual way.
For my question, let me first explain a simple case that the current event handling system of Android don't fits for me.
Supposing that I have a FrameLayout (that I'll call ViewSwiper since now) that all Views added on it are MATCH_PARENT X MATCH_PARENT (that I'll call PageView), it's handles events by translating the actual View and replace it based on the direction of moving.
This component I already have done and work properly ( Using Animation to swipe views ).
But the problem is on that PageView I add on top of it, in case of ImageViews that return false on it's onTouchEvent, the ViewSwiper will handle the events and let another PageView enter the screen, but if I add a ScrollView on that, all the events will be consumed by the Scroll and the ViewSwiper will not have chance to replace the PageView.
So I figured out that returning false onTouchEvent of the ScrollView the parent can assume it's events, I wrote this sub-class of ScrollView to test it:
public class ScrollViewVertical extends ScrollView {
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
}
public boolean onTouchEvent(MotionEvent evt) {
super.onTouchEvent(evt);
return false;
}
}
But returning false make any further events to get dispatched to the parent, but I need these events for VERTICAL scrolling, so I have the idea to return falses only if the user are moving HORIZONTAL, that's what my code looks like:
public class ScrollViewVertical extends ScrollView {
private MovementTracker moveTracker;
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
moveTracker = new MovementTracker();
}
public boolean onTouchEvent(MotionEvent evt) {
if (moveTracker.track(evt))
if (moveTracker.getDirection() == Direction.HORIZONTAL)
return false;
return super.onTouchEvent(evt);
}
}
PS: MovementTracker will returns true on track() after some events and tell on which direction the user is moving.
But in that case, the ScrollView keep receiving events since it's returns true on the first events.
Any ideas on how can I handle the events on ViewSwiper when it's child returns false (even if some trues are returned).
PS: I can give more info about this if needed, and accept different solutions also.
Based on answers I tried the following:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
onTouchEvent(ev);
return intercept;
}
public boolean onTouchEvent(MotionEvent evt) {
boolean x = super.onTouchEvent(evt);
if (moveTracker.track(evt)) {
intercept = moveTracker.getDirection() != Direction.VERTICAL;
if (!intercept)
getParent().requestDisallowInterceptTouchEvent(false);
}
return x;
}
Still nothing.
try this in onTouchEvent() of the scrollview
//if (evt.getAction() == MotionEvent.ACTION_MOVE) {
if (moveTracker.track(evt)){
if (moveTracker.getDirection() == Direction.VERTICAL){
//Or the direction you want the scrollview keep moving
getParent().requestDisallowInterceptTouchEvent(true);
}
}
return true;
Update
Please try the following to the custom Scrollview
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return false;
}
And nothing else
This way i assume the MotionEvent will perform on both views. And since they don't conflict (One is vertical the other one is Horizontal) this could work
Based on the answer from weakwire, I came to the following solution:
On ViewSwiper
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(!super.dispatchTouchEvent(ev))
onTouchEvent(ev);
return true;
}
And on ScrollHorizontal I return false on dispatchTouchEvent when I don't need then anymore.