I'm having an issue with the SwipeRefreshLayout. I have a list view within the layout and every time I scroll upward in the list view the swipe to refresh layout is tiggered and you can never scroll back to the top of the layout. Anyone have any ideas?
I found an answer to my question. I am manually enabling the swipeRefreshLayout when the first child in the listview is at the top of the list.
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView listView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int topRowVerticalPosition = (listView == null || listView.getChildCount() == 0) ?
0 : expandableListview.getChildAt(0).getTop();
refresh.setEnabled((topRowVerticalPosition >= 0));
}
});
https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html
According to Android docs at the above link,
This layout should be made the parent of the view that will be refreshed as a result of the gesture and can only support one direct child.
If the ListView is the 1st direct child of the SwipeRefreshLayout, refresh won't be triggered before scrolling back to the top of the ListView. You don't need to do anything in onScroll().
Related
I am building an application like techcrunch.
I am fetching data from server in JSON format and displaying the data in list view like article title,author name and image.
I have applied pagination means when user scroll more articles load in a list view. My pagination works fine but there is an issue in the scroll function as the fresh or new data loads the scroll dose not aligns with the data.
To clarify more in simple words my scroll-er goes at the top of the page when i am actually scrolling down
this is my code :
listView.setOnScrollListener(new AbsListView.OnScrollListener()
{
#Override
public void onScrollStateChanged(AbsListView absListView, int i)
{
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount){
if (mPreLast != lastItem)
{
mPreLast = lastItem;
onStart();
}
}
}
});`
You can use:
listView.setSelectionFromTop(newPosition, 0);
With this method you can set the position to a ListView, using the first parameter as the new position on the list, and the second parameter can be used to set the distance from the top
i have gridview with two column
user can scroll vertically to see gridview items
the problem is when user scrolling is finished
the first visible row is not completely seen .i want to set top of first visible row to top of gridview so first row is comletely visible
can anyone help me?
Update:
the first item is
and the second item is
but after scroll we see
you can try this
grid.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView arg0, int scrollState) {
//this is the state when scroll finish
if(scrollState==SCROLL_STATE_IDLE)
//the first visible item is the first (even partially) visbile item
//setSelection will scroll the grid to the beginning of such item
grid.setSelection(firstVisibleItem);
}
#Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
I use RecyclerView, and i hope it's good for you!
mLayoutManager = new GridLayoutManager(getActivity(), 2);
mListRV= (RecyclerView).findViewById(R.id.list_rv);
mListRV.setLayoutManager(mLayoutManager);
mListRV.setOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
View v = mLayoutManager.getChildAt(0);
int offsetTop = v.getTop();
int offsetBottom = v.getBottom();
int height = (offsetBottom - offsetTop);
if(offsetTop >= -height/2) {
mListRV.smoothScrollBy(0, offsetTop);
} else {
mListRV.smoothScrollBy(0, height + offsetTop);
}
}
}
});
With this code, when you finish scroll, if the first visible item only show a part in recyclerView. It will auto scroll to show full item. You can use:
mLayoutManager.scrollToPositionWithOffset(position, offset);
But it is so fast, the user can be confused. And you will not need use customLayoutManager to edit scroll's properties.
Hope that helps for you!
i have the ListView. I need hide header, it'll be search panel (simple layout with edit text).
Concretely: opened fragment with a listview, header (search panel) not visible, fill listview, if user scroll listview to the top - header showed. Something like PullToRefresh.
I tried add header to ListView#addHeaderView() and use setSelection(1), but if listview contains few rows, header showed whatever.
How can i make desired functionality?
You could try that with:
myListView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
myHeaderElement.setVisibility(View.GONE);
}
Consider I have two Horizontal ListView as shown below:
list1
list2
I want to know if it is possible to make the second list (list2) view scroll horizontally simultaneously along with the scroll of first list (list1).....
That is when I scroll list1 (horizontal), even list2 must scroll by the same offset...
Is this possible, if yes, please do help...
![link to image]: https://picasaweb.google.com/109389839906668906213/January132012#5697019272538269218
You can do that - just create such layout and use scroll events:
list1.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
list2.setSelectionFromTop(firstVisibleItem, list1.getChildAt(0).getTop());
}
});
Some explanation:
Better use list.setSelectionFromTop() than list.scrollTo() - because first visible item of first list can be shown partially.
list1.getChildAt(0).getTop() - is construction for getting value of X coordinate of first visible item.
As There is no HorizontalListView in Android, you must having another adapter view, anyway implement following:
list1.setOnItemSelectedListener(new OnItemSelectedListener()
{
public void onItemSelected(AdapterView adapterView adapterView, View view, int position, long id){
list2.setSelection(position);
}
});
just wanted to ask is there a possibility to bind some listener to the ListView scroll event.
What I would like to achieve is that once ListView have been scrolled to the bottom I would like to ask server for more data if any is there.
I know that there is a function like: getLastVisiblePosition() but I assume it must bu used in some kind of listener in order to compare with currently last visible position, am I right ?
cheers,
/Marcin
Just to extrapolate on TomTo's answer, some thoughts on how you might do this (theoretical, I haven't tried this in practice):
ListView lv = (ListView)findViewById(R.id.list_view);
lv.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//Check if the last view is visible
if (++firstVisibleItem + visibleItemCount > totalItemCount) {
//load more content
}
}
});
Since firstVisibleItem is returns an index (0-based), I increment by one to get the actual item number. Then, if that, plus the number of visible items, is greater than the total number of items, then in theory the last view should be visible. Shouldn't be a problem, but keep in mind this isn't called till the scrolling is finished.
used
if (++visibleItemCount > totalItemCount)
instead
if (++firstVisibleItem + visibleItemCount > totalItemCount)
AbsListView.OnScrollListener ?