I am trying to get a ListView to realign after every scroll/fling. By realign I mean realign in such a way, that the top item of the ListView is aligned with the top of the ListView, if it is cut off it should scroll down smoothly until it is realigned and fully visible.
I implemented a scroll-listener:
firstRowListView.setOnScrollListener(new OnScrollListener() {
private boolean correcting = false;
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
#Override
public void onScrollStateChanged(AbsListView arg0, int scrollState) {
if (!correcting && scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
correcting = true;
firstRowListView.smoothScrollToPosition(firstRowListView.getFirstVisiblePosition());
correcting = false;
}
}
}
});
(For easier visibility I only left the important bits in). If I scroll smoothly (no fling) it works fine, but if I fling the list it doesn't realign itself. Although LogCat tells me that the onScrollStateChange-method is executed in the same way as when I perform a "normal" scroll.
Why is this and how do I get the ListView to realign even after a Fling?
Following should work but on Galaxy tab 7 (4.0.4) I can see recursion happening. So I would strongly suggest that you implement some mechanism to avoid that otherwise this solution will break on some devices:
mylv.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
#Override
public void onScrollStateChanged(final AbsListView lv,
int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
lv.post(new Runnable() {
#Override
public void run() {
lv.smoothScrollToPosition(lv
.getFirstVisiblePosition());
}
});
}
}
});
On older devices ListView does not report SCROLL_STATE_IDLE after SCROLL_STATE_TOUCH_SCROLL. Please use workaround mentioned here . http://code.google.com/p/android/issues/detail?id=5086#c7
You can also remove correcting variable safely, as it is of no use in this code.
Related
I can detected when I scroll until the very bottom using
.size() - 1 of my elem. But if I start to scroll up at the middle of the list, how can I know it, in the method GetView() of course.
Found a way to do it which works more or less well...
list.setOnScrollListener(new AbsListView.OnScrollListener() {
private int mLastFirstVisibleItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(mLastFirstVisibleItem<firstVisibleItem) /* DOWN */
{
scrolling = false;
}
if(mLastFirstVisibleItem>firstVisibleItem) /* UP*/
{
scrolling = true;
}
mLastFirstVisibleItem=firstVisibleItem;
}
});
I need something like a table with two columns and dynamic no. of rows (which increases and decreases according to the length of data i receive ). Currently what I have done is, I added to listviews in a horizontal linear layout so it looks like a table. But the issue is both the listview's scrolling is independent of other. I need to lock the scrolling so if i scroll both will not move independently.
All the data in the listview are readonly (just for display purpose).
is it possible to sync the scroll or is there any better way by which my requirements can be met?
If you you want to stop the first list view scroll while scrolling the 2nd list and vice versaa other.Then put the Scroll listner for the lsitviews and block the other listview scrolling. here is example
listview1.setOnScrollListener(new OnScrollListener() {
private int mLastFirstVisibleItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
listview1.setEnabled(true);
listview2.setEnabled(true);
Log.i("a", "scrolling stopped...");
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
listview2.setEnabled(false);
}
});
Same way for the second list view
listview2.setOnScrollListener(new OnScrollListener() {
private int mLastFirstVisibleItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
listview1.setEnabled(true);
listview2.setEnabled(true);
Log.i("a", "scrolling stopped...");
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
listview1.setEnabled(false);
}
});
I am having two listviews in parallel on single screen. Both are having their own scroll listener.
What I want to do is scroll the first listview, then the second listview should also scroll and vice versa.
Is this possible ?
Suppose your ListViews are mListView1 and mListView2, then do something like this -
mListView1.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// Smooth scroll mListView2 according to mListView1.
mListView2.smoothScrollToPosition(firstVisibleItem);
}
#Override
private void isScrollCompleted() {}
});
When I combine both libraries in an activities, there is a problem.
When scroll to bottom is fine but when scroll to top there is a problem.
For example, the listview section in in middle and scroll up, the happen should be listview scroll up but it happened the actionbar refresh.
I suspected the both libraries's gesture overlap and causing this problem.
If I use them separately, both of them work brilliant.
Use the following snippet.This might Help you
listview.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (listview.getChildCount() > 0 && listview.getChildAt(0).getTop() == 0
&& listview.getFirstVisiblePosition() == 0) {
mPullToRefreshLayout.setEnabled(true);
}else{
mPullToRefreshLayout.setEnabled(false);
}
}
});
I am having this trouble when developing an endless listview..As I scroll down to the bottom I fetch more data and update the listview, however it goes back to the top of the list. What else to I need to make the list load new item but not changing the position? Please help, Thx!
streamLV.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
if(loadMore){
dosomething to get the items..then
lvAdapter.addItem(item);
}
streamLV.setAdapter(lvAdapter);
}
}
});
Try calling lvAdapter.notifyDatasetChanged() instead of setting it again on the ListView (instead of calling streamLV.setAdapter()).