I am trying to apply swipe refresh in expandable listView, when the list view is scrolled to bottom and I try to scroll up, then it doesn't scroll up, the swipe refresh layout activates, How to solve this problem? any idea.!!!
swipeRefreshLayout.setEnabled(false);
expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int topRowVerticalPosition = (expandableListView == null || expandableListView.getChildCount() == 0) ? 0 : expandableListView.getChildAt(0).getTop();
swipeRefreshLayout.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0);
}
});
Related
The issue I am having is that the expandable list view is able to scroll down properly, but when I try scrolling up on the expandable list view, it starts the refresh. I am able to scroll up on the expandable list when it first swipe down, and then up again. I want to know if it is possible to only refresh the expandable list when they are at the top of the list or to properly scroll up. I know that a list view has a onScrollListener, so is there something similar to expandable lists? Any help or other suggestion are welcome
Thanks
swipeRefreshLayout.setEnabled(false);
expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int topRowVerticalPosition = (expandableListView == null || expandableListView.getChildCount() == 0) ? 0 : expandableListView.getChildAt(0).getTop();
swipeRefreshLayout.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0);
}
});
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean allow = false;
if(visibleItemCount>0) {
long packedPosition = elvMounters.getExpandableListPosition(firstVisibleItem);
int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);
int childPosition = ExpandableListView.getPackedPositionChild(packedPosition);
allow = groupPosition==0 && childPosition==-1 && elv.getChildAt(0).getTop()==0;
}
mSwipeRefreshLayout.setEnabled(allow);
}
I have implemented GriView which contains 10 rows and 3 columns.when we are doing scrolling vertically on grid view. Item view of gridview is visible partially. Please find my code in below.
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
currentFirstVisibleItem = firstVisibleItem;
currentVisibleItemCount = visibleItemCount;
}
private void isScrollCompleted() {
if (gridView.getLastVisiblePosition() == gridView.getAdapter().getCount() - 1
&& gridView.getChildAt(gridView.getChildCount() - 1).getBottom() <= gridView.getHeight()) {
if (this.currentVisibleItemCount > 0 && currentScrollState == SCROLL_STATE_IDLE) {
gridView.smoothScrollToPosition(-1);
}
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
currentScrollState = scrollState;
isScrollCompleted();
}
}
I m looking to fire some function when the listview header view top edge appears on the phone.
How can you listen to header view y axis position changes ?
lv.setOnScrollListener(new OnScrollListener() {
private int lastFirstVisibleItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(lastFirstVisibleItem<firstVisibleItem)
{
Log.i("SCROLLING DOWN","TRUE");
}
if(lastFirstVisibleItem>firstVisibleItem)
{
Log.i("SCROLLING UP","TRUE");
}
lastFirstVisibleItem=firstVisibleItem;
}
});
listView.setOnScrollListener(new OnScrollListener() {
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean topOfFirst = listView.getChildAt(0).getTop() == 0;
if (topOfFirst) {
//Do something
}
}
}
The header should take position 0 in a ListView so the boolean will be set to true when the top of position 0 is visible.
I found another way. You can use view.getTop() and view.getBottom() , in this case the view will be the inflated list header.
I am trying to know when the user has scrolled to the top or bottom of the listview and he cannot scroll anymore.
Now i'm using OnScrollListener to know what listview items are visible.
listview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (totalItemCount - visibleItemCount == firstVisibleItem) {
//last item visible
}
if (firstVisibleItem == 0) {
//first item visible
}
}
});
I have found a solution by checking the offset of the first or the last item, when the offset of those items is 0 then we have reached the bottom/top of the listview.
listview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0) {
// check if we reached the top or bottom of the list
View v = listview.getChildAt(0);
int offset = (v == null) ? 0 : v.getTop();
if (offset == 0) {
// reached the top:
return;
}
} else if (totalItemCount - visibleItemCount == firstVisibleItem){
View v = listview.getChildAt(totalItemCount-1);
int offset = (v == null) ? 0 : v.getTop();
if (offset == 0) {
// reached the bottom:
return;
}
}
}
});
Try this way
list.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
int mPosition=0;
int mOffset=0;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int position = list.getFirstVisiblePosition();
View v = list.getChildAt(0);
int offset = (v == null) ? 0 : v.getTop();
if (mPosition < position || (mPosition == position && mOffset < offset)){
// Scrolled up
} else {
// Scrolled down
}
}
});
adapter getView method call when scroll listview
check the position when your position is equal to data size list view so you are on last element of list
#Override
public void onScrollChanged()
{
// We take the last son in the scrollview
View view = (View) scrollview.getChildAt(scrollview.getChildCount() - 1);
int diff = (view.getBottom() - (scrollview.getHeight() + scrollview.getScrollY()));
if (diff == 0 )
{
// bottom of the scrollview
}
}
If you are using a custom adapter with your
listview, then use and enjoy this answer:
https://stackoverflow.com/a/55350409/1845404
The adapter's getView method detects when the list has been scrolled to the last item. It also adds correction for the rare times when some earlier position is called even after the adapter has already rendered the last view.
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);
}
}
});