android - se llama a onScroll cuando establezco listView.onScrollListener(esto), pero sin ningún toque
android-listview (5)
¡Solución trabajada para mí! combinación de la respuesta anterior, ¡hice la solución! gracias a @LuxuryMode y @CrazyGreenHand
My TouchListener: desde que MotionEvent.ACTION_SCROLL no se activó, utilicé MOVE action
expandableListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(view == expandableListView && motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
userScrolled = true;
}
return false;
}
});
Mi oyente de desplazamiento:
expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0){
swipeRefreshLayout.setEnabled(true);
}else {
swipeRefreshLayout.setEnabled(false);
}
int lastVisibleItem = absListView.getLastVisiblePosition();
if (userScrolled&&!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
onLoadMore();
isLoading = true;
}
Log.d(TAG, "onScroll: firstVisibleItem=>"+firstVisibleItem+"==>visibleItemCount=>"+visibleItemCount+"==>totalItemCount==>"+totalItemCount+"==>lastVisibleItem==>"+lastVisibleItem);
}
});
Cuando configuro onScrollListener
para mi ListView
, llama onScroll
. Esto causa un bloqueo porque ciertas cosas no se han inicializado.
¿Esto es normal? Nota: esto está sucediendo sin que yo toque el teléfono.
public class MainActivity1 extends Activity implements OnClickListener, OnScrollListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
ListView lv = (ListView)findViewById(R.id.listview1);
lv.setOnScrollListener(this);
...
}
...
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount){
if( firstVisibleItem+visibleItemCount == totalItemCount ){
pullContactList();
}
}
Es normal porque el código fuente de setOnScrollListener
en AbsListView
(la superclase de ListView
) hace esto:
public void setOnScrollListener(OnScrollListener l) {
mOnScrollListener = l;
invokeOnItemScrollListener();
}
y invokeOnItemScrollListener
hace esto:
/**
* Notify our scroll listener (if there is one) of a change in scroll state
*/
void invokeOnItemScrollListener() {
if (mFastScroller != null) {
mFastScroller.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
}
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
}
onScrollChanged(0, 0, 0, 0); // dummy values, View''s implementation does not use these.
}
dependiendo de qué es lo que intentas hacer, hay varias maneras de evitar este problema.
EDITAR:
Como solo desea hacer esto si el usuario realmente se desplazó, supongo que podría hacer algo como:
lv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(view == lv && motionEvent.getAction() == MotionEvent.ACTION_SCROLL) {
userScrolled = true;
}
return false;
}
});
Entonces..
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount){
if(userScrolled && firstVisibleItem+visibleItemCount == totalItemCount ){
pullContactList();
}
}
});
Puede hacer la tarea necesaria solo cuando visibleItemCount> 0;
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount){
if (visibleItemCount > 0 ){
//perform the task to be done
}
}
Solo un recordatorio, de acuerdo con el javadoc de
MotionEvent.ACTION_SCROLL :
Esta acción siempre se entrega a la ventana o vista debajo del puntero, que puede no ser la ventana o vista que se toca actualmente.
Esta acción no es un evento táctil, por lo que se envía a onGenericMotionEvent (MotionEvent) en lugar de onTouchEvent (MotionEvent).
Por lo tanto, motionEvent.getAction()
nunca obtendrá el evento SCROLL. Verificar si MOVE hará el trabajo
También puede hacer algo similar en el método onScrollStateChanged
de OnScrollListener
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
userScrolled = true;
}
}
Uso esta solución y funciona bien para mí:
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
canScroll = false;
} else if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING ||
scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
canScroll = true;
}
}