I have a ScrollView that contains an number of other views (TextViews, ImageViews, etc.). The ScrollView is taller than the screen. I have an AsyncTask that updates the children of the ScrollView based on an http response.
I've discovered an interesting behavior that I can't figure out how to work around. If I set any of the children's visibilities to View.INVISIBLE as part of the AsyncTask.onPostExecute(), everything works fine.
However, if I set any of the children's visibilities to View.GONE, the ScrollView jumps down from the top when onPostExecute() is called. Exactly how far seems to vary. I'm guessing that re-laying out the ScrollView is causing it to scroll away from the top for some reason.
So the question is: is there a way to either prevent or work around this behavior?
PS. Using ScrollView.jump(FOCUS_UP) as a workaround isn't ideal since that'll force the user to the top even if they had intended to scroll down.
EDIT: Actually, I was wrong. The problem wasn't with a child view being marked gone, the problem was with a sibling view being marked gone and the ScrollView getting resized. My ScrollView is inside a LinearLayout that also contains a Button. When the button is set to GONE, the ScrollView gets resized to take up the available space, causing it to scroll away from the top. Different cause, still looking for a workaround though if possible.
I had the same problem. If layout jumping add tha following in ur top lever layout
android:descendantFocusability="blocksDescendants"
Example:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants" >
Related
I have a NestedScrollView which contains a view that is too large to fit on the screen (hence needing the scroll). There are various TextView elements that get updated fairly often (roughly every five seconds), and when they update the NestedScrollView scrolls to the top, completely forgetting where it was previously.
I have tried the solutions posted in "similar" questions, which primarily involve some version of the following:
In the TextView set android:focusable="true" and android:focusableInTouchMode="true"
In the parent layout (in my case, ConstraintLayout), set android:descendantFocusability="blocksDescendants"
I have updated all of the relevant views to include these, but the view still scrolls to the top whenever the TextView elements are updated. Has anyone had any luck in fixing something like this?
My UI consists of a ScrollView that takes the top 50% of the screen and under that two buttons that are attached to the bottom of the screen; YES and NO. The content of Scrollview is text that for most phones does not fill up the visual area of the ScrollView. However sometimes the text can be longer, such that it fills beyond the visual area of the ScrollView, hence the reason I added the ScrollView.
My problem is this; even when the ScrollView has very little text and does not need to scroll to show all of its content it still scrolls. The user can scroll the content up a slight amount. I'd like the View to instead not allow any scrolling if all the content is visible.
Is there an easy way to achieve this? Or do I have to implement that myself?
You cannot disable the scrolling of a ScrollView. You would need to extend to ScrollView and override the onTouchEvent method to return false when some condition is matched. To get help with extending, please read the answers to Disable ScrollView Programmatically?
I have a scrollView in my ViewPager fragment. I want to set the initial scrollView position to (0,100).
I tried setting scrollView.scrollTo(0,100) in onCreateView(). It didn't work.
Then I tried the same in Handler and it worked but it only scrolls to (0,100) after (0,0) causing little jerk in scrollView which is bad for user experience.
Is there any way to to make scrollview directly scroll to (0,100) instead of (0,0)? or Is there any method available in scrollView to detect initial scroll event?
P.S :I saw the question here which also the same as mine but the accepted answer is not working for me.
Any help would be appreciated.
Thanks
Instead of scrollTo you can use requestFocus on first child of inner layout of scroll view.
Example:
<ScrollView>
<LinearLayout>
<TextView
android:focusable="true"
android:focusableInTouchMode="true"
android:tag="ScrollTopTag" />
//***rest of your layout***//
</LinearLayout>
</ScrollView>
In your activity where you want to scroll to top of scroll view add below line
View view = findViewByTag("ScrollTopTag);
view.requestFocus();
It feels like you are inflating views inside the adapter without recycling them. This would explain the choppy loading times. Other than that, from the example, try delaying it even more. In the example it uses 250ms, but if your listview it not done loading than its not going to scroll anywhere since it is not filled yet. I would start off but first increasing the duration to about 2000ms just to see if it works. If that works, I would go back to your adapter class and make sure each view is recycling instead of reinflated.
I have a ScrollView with a RelativeView beneath it. Within that RelativeView, there are 3 views in it. 2 of those 3 are initially hidden.
Even though on my phone the scroller_rel doesn't take up the whole screen, I can still scroll through as if scroller_rel2 and scroller_rel3 are there and not hidden.
Programmatically I will decide if scroller_rel2 and scroller_rel3 are hidden or visible, and I'm wondering how to also then decide if we should be able to scroll or not.
The easy way to ask this question is: How can I programmatically tell ScrollView the height of the visible contents, so that if the contents are not larger than the container, we disable scrolling, and if say 2 of the 3 are showing, how can we then enable scrolling only to the bottom of scroller_rel2?
The reason you're having this problem is because setting the view to be View.INVISIBLE does just that, but it still takes up space in your layout, so that's why you can still scroll. What you should be using is View.GONE, this actually sets the view to be invisible and it removes it from the layout. Check out the documentation here:
GONE
INVISIBLE
I have a ScrollView layout like this, for example:
<ScrollView>
<Component1>
<Component2>
<Component3>
<Component4>
...
</ScrollView>
Inside ScrollView I have some components, each of them can be anything like LinearLayout, RelativeLayout, TableRow, ...
Now what I want is I will scroll the view, when the <Component2> reach the top of the screen, it will be keep on the screen and <Component3>, <Component4>... will keep scrolling till the end of page. When I scroll down, <Component2> will only be scrolled when all the <Component3> has became visible. I saw this on an Iphone app and wondered how to achieve this on Android.
I don't know if I describe clearly enough but it is same like this video
http://www.youtube.com/watch?v=jXCrM1rzLZY&feature=player_detailpage#t=71s
When the tabs scrolled up to top, it stay there. And when scrolled down like in 1:36 of that video, it stay there until all the content below has became visible on the screen.
Does anybody know how to do this on Android?
I guess you could create a hidden copy of Component2 in a RelativeLayout that is setVisible(true) when the coordinates of Component2 are lower(Android draws from the top) than the top of the ScrollView. When the coordinates of Component2 are higher than the top of the ScrollView (.getTop()), Component2Copy.setVisible(false).
You may also want to disable them when changing their visibility. Good luck with this.