valor una studio seleccionado programacion obtener móviles lista evento desarrollo datos curso aplicaciones android android-listview

una - Android obtiene la posición de desplazamiento exacta en ListView



obtener valor de una lista android (8)

Me gustaría obtener la posición exacta de píxel del desplazamiento ListView. Y no, no me refiero a la primera posición visible.

¿Hay una manera de lograr esto?


De acuerdo, encontré una solución, usando el siguiente código:

View c = listview.getChildAt(0); int scrolly = -c.getTop() + listview.getFirstVisiblePosition() * c.getHeight();

La forma en que funciona es la compensación real del primer elemento visible de la lista y calcula qué tan lejos está de la parte superior de la vista para determinar cuánto estamos "desplazándonos" en la vista, por lo que ahora sabemos que podemos calcular el resto usa el método getFirstVisiblePosition normal.


La idea más simple que pude idear fue ampliar ListView y exponer el "computeVerticalScrollOffset" que está protegido por defecto, luego usar "com.your.package.CustomListView" en sus diseños xml.

public class CustomListView extends ListView { public CustomListView(Context context) { super(context); } public CustomListView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public int computeVerticalScrollOffset() { return super.computeVerticalScrollOffset(); } }


La respuesta de Saarraz1 solo funcionará si todas las filas en la vista de lista tienen la misma altura y no hay encabezado (o también tiene la misma altura que las filas).

Tenga en cuenta que una vez que las filas desaparecen en la parte superior de la pantalla, no tiene acceso a ellas, ya que no podrá hacer un seguimiento de su altura. Es por eso que necesita guardar esas alturas (o alturas acumuladas de todas). Mi solución requiere mantener un diccionario de alturas por índice (se supone que cuando la lista se muestra la primera vez que se desplaza hacia arriba).

private Dictionary<Integer, Integer> listViewItemHeights = new Hashtable<Integer, Integer>(); private int getScroll() { View c = listView.getChildAt(0); //this is the first visible row int scrollY = -c.getTop(); listViewItemHeights.put(listView.getFirstVisiblePosition(), c.getHeight()); for (int i = 0; i < listView.getFirstVisiblePosition(); ++i) { if (listViewItemHeights.get(i) != null) // (this is a sanity check) scrollY += listViewItemHeights.get(i); //add all heights of the views that are gone } return scrollY; }


Me enfrenté al problema similar, que quería colocar Vertical Seekbar en el valor de desplazamiento actual de ListView . Así que tengo mi propia solución como esta.

Primera clase de creación

public abstract class OnScrollPositionChangedListener implements AbsListView.OnScrollListener { int pos; public int viewHeight = 0; public int listHeight = 0; @Override public void onScroll(AbsListView v, int i, int vi, int n) { try { if(viewHeight==0) { viewHeight = v.getChildAt(0).getHeight(); listHeight = v.getHeight(); } pos = viewHeight * i; } catch (Exception e) { e.printStackTrace(); } finally { onScrollPositionChanged(pos); } } @Override public void onScrollStateChanged(AbsListView absListView, int i) {} public abstract void onScrollPositionChanged(int scrollYPosition); }

Entonces úsala en la actividad principal como esta.

public class MainActivity extends AppCompatActivity { SeekBar seekBar; ListView listView; OnScrollPositionChangedListener onScrollPositionChangedListener = new OnScrollPositionChangedListener() { @Override public void onScroll(AbsListView v, int i, int vi, int n) { super.onScroll(v, i, vi, n); //Do your onScroll stuff } @Override public void onScrollPositionChanged(int scrollYPosition) { //Enjoy having access to the amount the ListView has scrolled seekBar.setProgress(scrollYPosition); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = (SeekBar) findViewById(R.id.mySeekBar); listView = (ListView) findViewById(R.id.listView); final String[] values = new String[]{"Android List View", "Adapter implementation", "Simple List View In Android", "Create List View Android", "Android Example", }; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values); listView.setAdapter(adapter); listView.setOnScrollListener(onScrollPositionChangedListener); seekBar.postDelayed(new Runnable() { @Override public void run() { seekBar.setMax((onScrollPositionChangedListener.viewHeight * values.length) - onScrollPositionChangedListener.listHeight); } }, 1000); seekBar.setEnabled(false); } }

en App Gradle

compile ''com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:0.7.0''

En diseño XML

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.centsol.charexamples.MainActivity"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:fadeScrollbars="false" android:scrollbars="none" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> </ListView> <!-- This library requires pair of the VerticalSeekBar and VerticalSeekBarWrapper classes --> <com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper android:layout_width="wrap_content" android:layout_alignParentRight="true" android:layout_height="match_parent"> <com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBar android:id="@+id/mySeekBar" android:layout_width="0dp" android:progressDrawable="@drawable/progress" android:thumb="@drawable/thumb" android:layout_height="0dp" android:splitTrack="false" app:seekBarRotation="CW90" /> <!-- Rotation: CW90 or CW270 --> </com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper> <View android:layout_width="1dp" android:visibility="visible" android:layout_alignParentRight="true" android:layout_marginTop="16dp" android:layout_marginRight="2.5dp" android:layout_marginBottom="16dp" android:background="@android:color/black" android:layout_height="match_parent" /> </RelativeLayout>

fondo xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="@android:color/transparent"/> </shape>

llenar xml

<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="@android:color/transparent" /> </shape>

progreso xml

<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@android:id/background" android:drawable="@drawable/background"/> <item android:id="@android:id/progress"> <clip android:drawable="@drawable/fill" /> </item> </layer-list>

pulgar xml

<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="@android:color/holo_red_dark" /> <size android:height="5dp" android:width="5dp" /> </shape>


Primero declare su variable int para mantener la posición.

int position = 0;

luego agrega scrollListener a tu 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) { position = firstVisibleItem; } });

Luego, después de obtener nuevos datos o cualquier cambio en sus datos esa vez, necesita configurar la vista actual de la lista

listView.setSelection(position);

Lo he usado después de configurar mi adaptador, funciona bien para mí ...


Sé que llego tarde a la fiesta, pero quería compartir mi solución a este problema. Tengo un ListView y estaba tratando de encontrar cuánto he desplazado para desplazar algo más en relación con él y provocar un efecto de paralaje. Aquí está mi solución:

public abstract class OnScrollPositionChangedListener implements AbsListView.OnScrollListener { int pos; int prevIndex; int prevViewPos; int prevViewHeight; @Override public void onScroll(AbsListView v, int i, int vi, int n) { try { View currView = v.getChildAt(0); int currViewPos = Math.round(currView.getTop()); int diffViewPos = prevViewPos - currViewPos; int currViewHeight = currView.getHeight(); pos += diffViewPos; if (i > prevIndex) { pos += prevViewHeight; } else if (i < prevIndex) { pos -= currViewHeight; } prevIndex = i; prevViewPos = currViewPos; prevViewHeight = currViewHeight; } catch (Exception e) { e.printStackTrace(); } finally { onScrollPositionChanged(pos); } } @Override public void onScrollStateChanged(AbsListView absListView, int i) {} public abstract void onScrollPositionChanged(int scrollYPosition); }

Creé mi propio OnScrollListener donde se llamará el método onScrollPositionChanged cada vez que se llame aScroll. Pero este método tendrá acceso al valor calculado que representa la cantidad en que se ha desplazado ListView.

Para utilizar esta clase, puede configurar OnClickListener en un nuevo OnScrollPositionChangedListener y anular el método onScrollPositionChanged.

Si necesita utilizar el método onScroll para otras cosas, puede anularlo también, pero debe llamar a super.onScroll para que onScrollPositionChanged funcione correctamente.

myListView.setOnScrollListener( new OnScrollPositionChangedListener() { @Override public void onScroll(AbsListView v, int i, int vi, int n) { super.onScroll(v, i, vi, n); //Do your onScroll stuff } @Override public void onScrollPositionChanged(int scrollYPosition) { //Enjoy having access to the amount the ListView has scrolled } } );


Si alguien más encontró esto en Google mientras buscaba una manera de rastrear desplazamientos de desplazamiento relativos en un OnScrollListener, es decir, cambiar en Y desde la última llamada al oyente, aquí hay un resumen que muestra cómo calcular eso .


además de la respuesta de . ListView no contiene todos los elementos en su desplazamiento, por lo que debe operar solo la parte "visible" de la lista. Cuando se desplaza hacia abajo, los elementos superiores se desplazan y se empujan como nuevas vistas de elementos. Así es como viene ConvertView (no es un elemento vacío para llenar, es un elemento desplazado que está fuera de la parte "visible" de la lista. Así que debes saber cuántos elementos estaban antes de la parte visible multiplicarlos con ListItemHeight y agrega headerHeight, thes how puede obtener un desplazamiento absoluto real en desplazamiento. Si no tiene encabezado, la posición 0 será listItem, por lo que puede simplificar absoluteY += pos*listItemHeight;

public class CustomListView extends ListView { private int listItemHeight = 140; private int headerHeight = 200; public CustomListView(Context context) { super(context); } public CustomListView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public int computeVerticalScrollOffset() { final int y = super.computeVerticalScrollOffset(); int absoluteY = y; int pos = getFirstVisiblePosition(); if(pos > 0){ absoluteY += (pos-1)*listItemHeight+header‌​Height; } //use absoluteY return y; }