How do you find the bottom scrollable position in a ScrollView? - android

In an android scrollView, how do you find the lowest position in the scrollview so you can then use the scrollTo(x,y) method to scroll right to the bottom. I need the actual numeric value. Using the getHeight() method does not ever return the right value. The scrollbar will sometimes scroll to the end, and sometimes not reach it. There is a linearlayout with a textview in the scrollview. There has to be something that I am missing?

If you want to just scroll to the end, you should be able to just use fullScroll(ScrollView.FOCUS_DOWN). If you need a particularly numerical value based on the height of the scroll view, you will have to subclass your scroll view and override onSizeChanged, which will give you the actual numerical height. Keep in mind onSizeChanged will only be called after onResume, and will not necessarily be called every time your activity resumes.
Part of the reason why you sometimes scroll to the end and sometimes don't is probably because of a race condition. Sometimes your scroll happens before other important things (like populating the view) have happened, so it doesn't appear to do anything.
Try posting your calls to your scroll view's handler:
yourScrollView.post(new Runnable(){
#Override
public void run(){
yourScrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
};
Sometimes even adding a short delay can help:
yourScrollView.postDelayed(new Runnable(){
#Override
public void run(){
yourScrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
}, 200);

Thanks for the response. I found a quick hack if anyone is interested.
sView.fullScroll(View.FOCUS_DOWN);
sView.fullScroll(View.FOCUS_DOWN);
y = sView.getScrollY();
sView.fullScroll(View.FOCUS_UP);
This will jump down to the bottom of the scrollable, collect y, then jump up again. It happens so fast it is not visible and it will get you the bottom value of y every time. You have to call focus down twice or else y will return 0.

Related

Setting android view location has no effect

I have a simple view inside of a RelativeLayout that I animate up & down so it slides off and on screen. This works every time except the very first time, where the animation does nothing.
This lead me to trying to set the Y location manually in the activity's onCreate() method. Oddly, that had no effect either.
Is there some reason a view's Y location can't be set until after the activity has been fully displayed? If not, why am I seeing this weird behavior, and is there a way to fix it?
The first time you're calling it's before the view has laid out.
You can get around this by listening for the view to be laid out.
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Perform whatever actions you want here
}
});

Scrolling is delayed when inflating view

Hope you can help me, this has been bugging me for quite some time now-
I have an activity that at some point inflates a view which has its own layout and logic behind. This view contains a ScrollView which I want to be scrolled down x dp when its shown to the user (I don't want user to actually see the scrolling, I want ScrollView to be at the right position as the view displays).
Here's what I tried so far:
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, someInnerView.getBottom());
}
});
I've tried using this code in different parts of my view logic such as onFinishInflate() but that doesn't work as the data isn't binded to the view at that point. So I added OnGlobalLayoutListener and called the Runnable inside onGlobalLayout() which does work but with a short delay which can clearly be detected.
How do I solve this problem? All I want to do is to have some part of my ScrollView hidden when it's presented to the user.
All help appreciated!
EDIT : to make my intentions clearer- I want to create something similar to this, only that I'm using ScrollView

Get the position of scrollbars(not the position item) in a ListView

I am implementing a timeline UI, which is basically a ListView. The tricky part is when the user scrolls the ListView, it will display a text box(shows the time slot, say 9:00 am ) next to the scrollbar. It is on the left side, adjacent and will move with the scrollbar.
I am using the OnScrollListener to detect the scroll event. But I don't know how to get the exact position of the scroll bar (top, mid point, bottom), so that I can put the text box at the right place. There are many posts about getting the position of the top item but seems not for the scrollbar itself.
Any thoughts?
BTW, sorry for not attaching a screenshot of the UI. Stackoverflow doesn't allow me to do that since I am a new user.
But I don't know how to get the exact position of the scroll bar (top,
mid point, bottom), so that I can put the text box at the right place
You probably want something like the Path application. This tutorial it what you're looking for(probably, if you didn't see it yet).
Basically, the ListView has some methods regarding the scrollbars position(also size) that are used but those methods are not available from outside as they are declared as protected, so you need to extend the ListView class. Those methods are ListView.computeVerticalScrollExtent(), ListView.computeVerticalScrollOffset() and ListView.computeVerticalScrollRange().
Using those methods you should be able to figure where the scrollbars are placed at a particular moment in your listener.
getListView().getLastVisiblePosition()
listview.post(new Runnable() {
public void run() {
listview.getLastVisiblePosition();
}
});
View.getScrollY()
getScrollY:
Return the scrolled top position of this view. This is the top edge of the displayed part of your view. You do not need to draw any pixels above it, since those are outside of the frame of your view on screen.
Returns
The top edge of the displayed part of your view, in pixels.
Also refer : http://eliasbland.wordpress.com/2011/07/28/how-to-save-the-position-of-a-scrollview-when-the-orientation-changes-in-android/

Why is ScrollView sometimes (!) not scrolling when scrollTo is called (in an onClick event)

So I have this button (ImageView with onClick method) on the right side of the screen which when I pull it to the left extends into a SeekBar where you can select the time of day. To create this I have made a ScrollView with a horizontal LinearLayout with a see through view on the left and the "button"+SeekBar on the right (mostly outside of the screen). The "button" has an OnTouch and OnClick listener.
In the onTouch the scrollview is told to smoothScrollTo the correct location depending on where the finger is moving. When you move less than a certain threshold and release the onClick is called.
In the onClick I have told the scrollview to smoothScrollTo / scrollTo / fullScroll. The fullScroll didn't ever work. The smoothScrollTo works most of the time on one device (HTC Desire with Android 2.2.2) but never worked IN THE ONCLICK (?) on another device (Samsung Galaxy Tab (the old one) with Android 2.2). The scrollTo sometimes works on both devices... I am sure the onClick is called as I log that when it starts and also directly after telling the ScrollView to scroll.
I have tried posting the scrollTo to the ScrollView in a runnable and a delayed runnable:
scrollView.postDelayed(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(left, 0);
Log.d("SomeTag", "The scroller should scroll to: "+left);
}
}, 200);
But this worked just as often (so sometimes) as not posting it...
I am nonplussed. I am used to working with Android and used to different devices behaving differently, but I am not used to having the same call on the same device "sometimes" working and "sometimes" not... Any help would be greatly appreciated!
See this answer.
ScrollView.scrollTo() may not working if some layout changes are being made when you called the method. And you are right, using postDelayed() you cannot guarantee that layout changes in will always finish within the same delay time.

Android ViewFlipper measures of undisplayed child

I have a ViewFlipper on my main Activity's View. At onCreate I instante Views which are added to ViewFlipper. After that I set displayed child to first one. And when a button is clicked I switch ViewFlipper's display child to second view. Right after calling viewFlipper.setDisplayedChild(1) I need to do some calculations and instantate some objects which are based on width and height of displayed child.
Main problem here is that at first time (second = 1) child is displayed measurement of view is not done yet. So my width and height are 0. If I go back (setDisplayedChild(0)) and than goes back to second child it is ok (width and height are correct).
I have done some research about that behavior of views and found out that there is a method [onMeasure](http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)) which can be overrided and everything can be done here. OK that how it should be. Actually it is but problem is that onMeasure is called 4 times on each view switch. And my findings was that at first and third call width and height are full screen sized. The second and fourth call are proper width and height. Because I have to instantate new objects at that point it is unwise to do it in onMeasure.
Is there any other, proper way of doing it?
Is it possible to force measurement?
Do I really need to show view on screen for measurements?
Regards
Zmeda
Your init-action (based on width and height of displayed child) should be invoked after measuring of ViewFlipper's children, you can achieve that using method post, e.g.:
viewFlipper.setDisplayedChild(1);
viewFlipper.post(new Runnable() {
#Override
public void run() {
Log.d("test", "w: " + viewFlipper.getCurrentView().getWidth());// not 0
//do some calculations and instantate some objects
}
});

Categories

Resources