In my application i've a line for increasing the width of a widget(by dragging the line to right/left) and i've the ScrollView enabled in the same activity. I need to disable the scroll view action when the user touches the line and when user releases, it should be enabled. The ScrollView should be in visible state but the action of the scroll view should be disabled. Please help me in solving this problem. I've tried with these but none of them is working.
scroll.setEnabled(false);
scroll.setFocusable(false);
scroll.setHorizontalScrollBarEnabled(false);
scroll.setVerticalScrollBarEnabled(false);
Thanks in advance.
This might be a bit late but I ran into the same problem so my solution is similar to above, had to disable the OnTouchListener as follows:
// Get the ScrollView
final ScrollView myScroll = (ScrollView) findViewById(R.id.display_scrollview);
// Disable Scrolling by setting up an OnTouchListener to do nothing
myScroll.setOnTouchListener( new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
// Enable Scrolling by removing the OnTouchListner
tvDisplayScroll.setOnTouchListener(null);
This is a bit late, but an even easier way is to just get your parent ViewGroup and call requestDisallowInterceptTouchEvent(true) on it. This causes not only the immediate parent (scroll view) but any other parent objects that might intercept the touch to ignore it for the duration of the particular event. This is great when you have a draggable child AND draggable parent, and want to disable parent dragging while the child is being dragged.
It's also a more general solution than specifically disabling the scroll view. If you re-use your draggable child view somewhere else, it will still work: You don't need to know the scroll view's ID. Code that's re-usable without modification is always good.
If anyone's using Android L or later and overriding onTouch and onInterceptTouchEvent isn't working:
try overriding onStartNestedScroll and return false.
There is also a new XML attribute nestedScrollingEnabled, but it seems like it has to be on the View that is leaking the scroll event, rather than on the ScrollView being affected by the leak, or anywhere in the layout hierarchy between them. So if you don't know in advance what child ScrollViews you might have, overriding onStartNestedScroll for the affected ScrollView is the way to go.
Related
Flutter's DraggableScrollableSheet Widget allows a sheet to be dragged into position and then continue scrolling the content without the user needing to start a new gesture (lift their finger from the screen).
This Widget however relies on a single scroll controller being declared which makes adding say a Navigator into that sheet with multiple scrolling pages difficult.
Instead I tried to mimic the behaviour with a Listener Widget that replaces the Draggable element and an attachable scroll listener that can modify the scroll position of any ScrollController it is attached to until the draggable sheet (Listener) updates the state to say that scrolling is now allowed.
It works perfectly but relies on overriding the ScrollController's position:
// state variable
bool allowScroll = false
if(! allowScroll){
scrollController?.position.setPixels(0);
}
However, that may not be the most efficient way to go about it. Essentially I am overriding the ScrollPosition as apposed to ignoring gestures on the scrollable widget.
Other options such as:
Changing scroll physics from Never to Always
IgnorePointer / Absorb Pointer
Changing HitTestBehaviour
do not allow the same gesture to be used and require the user to lift their finger after the state change and initiate a new gesture. That would not be the correct behaviour. The above works correctly, it just feels like a hack and I wondered if there was a better approach.
I created a code that animates all the children of the ListView except the position 1.
if I reduce the application with the "home" button and I come back on, the animation of the view at position 1 is not launched. So if I press a "Preferences" button in the action bar which launches another activity, and then I press the "back" button, the animation is started.
Also, if I click on the item, the animation is started.
Finally, if I scroll to hide the view at position 1 and I scroll to draw again, the animation is started.
I do not think posting the code is useful because it works for all other views.
I tried to use the "convertView" of the Adapter, I also try to redraw the whole, it does not work.
I hope that the solution lies in an option to enable it in the ListView. Thank you.
I have the same problem. I just noticed that the view at position 1 is redrawn (in the getView method of the adapter) more times than others view.
Your listview layout_width and layout_height attr. are match_parent? If listview layout attrs are wrap_content, it called getView every width or height changing.
Optimize adapter code but your code want position variable shouldn't use. Because very dangerous row cached.
if( convertView == null){
// inflate
...
convertView.setTag(holder);
}else{
holder = ((Holder)convertView.getTag());
}
...
Other options very simply but not fast and memory friendly
// inflate convertView
convertView = inflater.inflate(, );
// than use convertViews child view
I have a view controller that looks like this:
The root view is a scroll view. When the view first loads, it scrolls just fine.
However, I sometimes need to remove one of the buttons at the bottom with code like this:
if (item.url==nil||[item.url isEqualToString:#""]) {
[overdriveButton removeFromSuperview];
}
After doing so, however, the scroll view will no longer scroll. (Those views in the middle of the screen expand, so there's always plenty of content that extends beyond the bottom of the screen).
Note that I am required to use Auto Layout here. My suspicion is that this is part of the problem. Does the removal of the button (and, necessarily, the associated constraints) somehow confuse the scroll view?
Either set UIScrollView's "contentSize" property, or call "sizeToFit" method.
I have a UIWebView which is embedded in a UIScrollView. The webView is resized so that the scroll view manages all the scrolling (I need control over the scrolling).
In the webView I have disabled userSelection via '-webkit-user-select: none;'
Everything is working fine except one annoying detail. When I hold down my finger on the content before starting to scroll for about a second the scrollView won't scroll. My best guess is, that it has something to do with userSelection. The time is about the same it usually takes for the copy/paste/magnifying-thing to appear which usually disables scrolling as well.
I am running out of ideas on how to solve this. Every help would be greatly appreciated!
Thanks!
EDIT: Another aspect of the problem is, that the non-scrolling actually triggers JS-Eventhandler (click, mousedown, mouseup) inside my webView which leads to surprising app behavior. The user puts her finger down, waits, scrolls, nothing happens, removes her finger and this is perceived as a click, which feels wrong from a users perspective.
I would guess what is happening is that after that short duration, the scrollview is no longer interpreting the touch as being on it's view and instead passes the touch down to it's content views.
Have you tried delaying the content touches for the scrollview? This will essentially tell the scrollview to delay taking action on the touch event and instead to briefly monitor the touch and if the touch moves then it recognizes it as a swipe gesture for scrolling. If it doesn't move, it will eventually pass the touch along to it's subviews.
scrollView.delaysContentTouches = YES;
I think even then, there is a standard delay time before the scrollview will pass the touch events along the responder chain. If you hold for too long, it's going to naturally perceive it as being a press down event rather than a scroll event.
This question is not relevant anymore. As of iOS 5.0 the UIWebView is based on a real UIScrollView and also exposes that UIScrollView via a property. Use that instead.
And don't mess with UIWebViews embedded in UIScrollViews anymore. The documentation explicitly advises against that.
Relevant Documentation
I'm using a UISwitch-Component at the bottom of a view that sits within a UIScrollView.
Now the problem that appeared, is that the switch is nearly impossible to swipe because the UIScrollView seems to dominate the userinput.
Switching works very well by tapping the switch, but from my point of view, most users "switch" the UISwitch instead of tapping.
Did anyone of you face the same / or similar problems and managed to come up with a solution?
thx in advance
sam
You have a design decision to make: if your content is meant to scroll horizontally, then a user swipe over a switch is ambiguous -- does it mean they want to scroll, or toggle the switch?
The easiest solution is to modify your UI so that this ambiguity disappears. For example, if the scroll's contentSize is not wider than the bounds of the scroll view, then it can't scroll horizontally, and a horizontal swipe will always activate the switch.
If you do want to allow horizontal scrolling, then it makes sense to replace the UISwitch with a UIButton that toggles on touch, similar to a play/pause button.
On the other hand, if you don't want to modify your UI, you could always just do:
myScrollView.delaysContentTouches = NO;
This will cause your switch to "get" the touches immediately, rather than have them go to the UIScrollView first. More info here. (You can also set this boolean in Interface Builder, as pointed out by Squeegy.)