Android touch event propagation - android

It's my understanding that Android event propagation goes from parent to child, that is to say, it starts with the outermost element and inwards from there. My question is, why is it that when I try to scroll vertically a listview that is inside a viewpager that is wrapped on a scrollview, the listview moves, and not the viewpager.
Okay, let me rephrase that:
I'm trying to create a menu that appears when the user pulls down the view pager, let me make that even clearer:
Scrollview
My custom Menu
ViewPager (with three fragments, all of them have a lisview)
ListView
I understand that what I'm trying to do is a bit odd, but bear with me just for this time. :)
What can I do to "disable" momentarily the list views scrolling.
Thanks

It seems you have to override the scrolling event. A good webpage is Disable scrolling in Android ListView .
Mainly look at dispatchTouchEvent. Snippet of it:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_MOVE) {
// Ignore move events
return true;
}
Personally I wish it is simpler than this like disabling scroll method.

Related

dispatchTouchEvent and onTouchEvent in Android

Helle there,
I've been working with the CoordinateLayout inside i have nestedScrollview layout and it's childs.
It's similar to whats'app profile view. I have tried to mimic this ontouch and dispatchtouch event for more than two days without success.
I read lot about dispatchTouch event onTouchEvent, setOntouchListener. and it's related video's.
I read about Managing ViewGroup reference in android reference, but still it's confuses me. How to handle those touch events.In nestedScrollView i have child linearlayout and this layout contains lot of child views like button and edittext.
When i touch nestedScrollview (ActionDown) triggered and subsequently (ActionUp) started to scroll, but when i touch any of it's child's view it should wait for the movement of my finger and then start to call nestedScrollview if its a (ActionMove).
I've dealing this inside of AppCompatActivity.
How do i achieve this? Please help.
Thanks.
Stupid enough to play with what i don't understand.
I was able to mimic like whatsapp profile,
#Override
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
nestedScrollview.onTouchEvent(motionEvent);
return super.dispatchTouchEvent(motionEvent);
}
call actionMove on child view to consume the event. Voila this did that trick. How ever the Scroll was not smooth compared to the mimic :0
Call this child.setOnTouchListener
case MotionEvent.ACTION_MOVE:
if (zeroY < mTouchSlop) {
mIsScrolling = true;
Log.d(DEBUG_TAG, "general" + Float.toString(zeroY) + " " + Float.toString(plusY));
}
return true;

How to make ViewPager scrollable from the parent view?

I was implementing the app tutorial which looks like this.
I made a nice and small ViewPager and placed it on the mock-up ImageView. The problem is that the ViewPager is not scrolled when I try to scroll it from elsewhere, say around the view pager indicators. This is so natural because there's no way that the ViewPager listens to touch event outside of itself.
How can I make ViewPager be scrolled when I try to scroll from elsewhere?
I've tried to detect touch events on the parent of the ViewPager but I couldn't figure out how to relate onFling() or onScroll() to ViewPager's scrolling.
If there's any better suggestion of implementing this kind of UI, what would be it?
Is there any tutorial or custom library similar to this?
set a View.OnTouchListener for your outer ViewPager and check inside if you are on proper page which is displaying inner ViewPager. if inner ViewPager isn't on its first or last you might dispatch MotionEvent to second dispatchTouchEvent(MotionEvent me)
outerViewPager.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(outerViewPagerAdapter.isCurrentPageHaveInnerViewPager() &&
! innerViewPagerAdapter.isOnFirstOrLastPage()){
innerViewPagerAdapter.dispatchTouchEvent(event);
return true;
}
return super.onTouch(event); //outer will get touch events
}
});
you might also adjust x/y touch cords in event before dispatching if needed

Create a linearview on every activity to perfom action

I am trying to create view that sites underneath all others that will perform an action when 3 fingers are touched. These activities all have their own touches and swipes.
I have got this to kind of work by creating a class that extends linearlayout and intercepting touches. and adding this in xml.
But this is only being called when an item like button or view is a clickable or touchable surface and isn't becoming a touchable surface itself.
in
public class MyCatcher extends LinearLayout {
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
// multitouch!! - touch down
int count = event.getPointerCount(); // Number of 'fingers' in this
if (count > 3) {
doThis(mContext);
}
}
return super.onInterceptTouchEvent(event);
}
And in xml
<packagename.MyCatcher
....>
my normal layout
</packagename.MyCatcher>
So this code is working when an item that is touchable is touched but not becoming its own touch layer.
I have tried setontouchlister in the constructor with no luck.
Thanks for any help
EXTRA: When setting the touchlistener via onAttach I can get it to catch touches but I can't use event.getPointerCount() like normal as it's returning 1.
I'm worried this may take up lots of processing?/
Instead of a Layout, create a normal View and add it to your existing layout so that it spans the whole screen and lays "above" all other views (in z-order). Now it should get all touch events prior to all other views. Your onTouch... implementation should make sure to pass all touch events along to the other views (except if you want e.g. buttons not to work under certain circumstances, then do not pass the events along).
onintercepttouchevent()
Is called only whenever a touch event is occured. ie; touch event occurs only when a view item like button,textbox,etc having onclicklistener enabled is pressed . For your question you need to set the onclicklistener for the entire view.

TextView inside ViewPager intercepts touch events

I have a ViewPager that contains two fragments. In any of the fragments I can touch a place, swipe to switch to another fragment. One of the fragments contains a list. Items in the list contains one TextView and one ImageView. The issue is, if you dragging has been started from tapping the ImageView, it's OK. But if it's been from the TextView, the drag was never known to the ViewPager, as a result the 'smooth switching' never happens.
Any clue on this?
EDIT
This picture is to show how my GUI is. If the drag has been started from TextViewE, it doesn't begin.
This thing bothered me too, but I've managed to find the answer.
Basically, the case is: if the view can scroll horizontally, it intercepts the horizontal motion event and ViewPager is not able to process it anymore.
Since API Level 14 TextViews have android:scrollHorizontally property (and setHorizontallyScrolling(boolean) method), which, if set to true, causes the TextView to intercept horizontal scroll motion events.
You may set it to false either in XML or right in the code, but watch out: android:singleLine property forces android:scrollHorizontally to be set to true! Very tricky point! But fortunately, you usually able to safely replace single line property with android:maxLines="1" and necessary ellipsize value.
Good luck!
you can override onTouchEvent() of the TextView:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
return false;
}
return super.onTouchEvent(event);
}

Android ListView, not all Touch-Events

I want to use a ListView (and have done this successfully before) containing custom Views.
Basically these custom views are vertical sliders, obviously conflicting with the natural behaviour of the ListView.
I fill it with my custom Views from an Adapter, and these react to the touches on the Items,
but once I move my finger more than a few pixels, it will scroll, and the custom View will not receive any touch-events anymore.
How can I (nicely) prevent the ListView from scrolling, when I touch my own components?
Can I somehow disable ListView Selection, and just forward the touches to the Items, but still use the scrolling behaviour?
Thank you in advance.
To prevent the scrolling of listview you can inplement on touch listener as follows
listView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_MOVE)
{
return true;
}
return false;
}
});
hope it will work and if it us useful to you give vote
You can intercept all touch events using onInterceptTouchEvent() in your root layout (one that contains the ListView, like a FrameLayout) as found here.
What you do there is capture the motion events (return true when a MotionEvent.ACTION_DOWN comes in), capture the following event in onTouchEvent(), decide whether the motion is meant for the list items or the list itself and accordingly dispatch the events.
Don't expect this to work easily. Understanding the flow of motion events and the interaction between onInterceptTouchEvent() and onTouchEvent() is challenging and making it work even more so. But I'm confident that this is a feasible way to solve your problem.

Categories

Resources