android android-listview onscroll

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; } }