Android получает точную позицию прокрутки в ListView

Я хотел бы получить точную позицию пикселя прокрутки ListView. И нет, я не имею в виду первую видимую позицию.

Есть ли способ достичь этого?

Хорошо, я нашел обходной путь, используя следующий код:

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

Как он работает, он принимает фактическое смещение первого элемента видимого списка и вычисляет, как далеко он находится от вершины представления, чтобы определить, сколько мы «прокручиваем» в представление, поэтому теперь, когда мы знаем, что мы можем вычислить остальные используют обычный метод getFirstVisiblePosition.

Ответ Saarraz1 будет работать только в том случае, если все строки в списке имеют одинаковую высоту, и нет заголовка (или он также имеет ту же высоту, что и строки).

Обратите внимание, что после того, как строки исчезнут в верхней части экрана, у вас нет доступа к ним, так как вы не сможете отслеживать их высоту. Вот почему вам нужно сохранить эти высоты (или накопленные высоты всех). Мое решение требует хранения словаря высот на индекс (предполагается, что при отображении списка при первом прокрутке вверх).

 private Dictionary listViewItemHeights = new Hashtable(); 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; } 

Самая простая идея, которую я мог придумать, заключалась в том, чтобы расширить ListView и выставить «computeVerticalScrollOffset», который по умолчанию защищен, а затем использовать «com.your.package.CustomListView» в ваших 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(); } } 

Если кто-то еще нашел это в Google, ища способ отслеживать относительные смещения прокрутки в OnScrollListener, то есть изменить Y со времени последнего вызова слушателя – вот Gist, показывающий, как его вычислить .

Сначала объявите переменную int для сохранения позиции.

 int position = 0; 

затем добавьте scrollListener в свой 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; } }); 

Затем, после получения новых данных или любых изменений в данных, вам необходимо установить текущую позицию списка

 listView.setSelection(position); 

Я использовал после настройки моего адаптера, отлично работает для меня.

Я знаю, что опаздываю на вечеринку, но я решил поделиться своим решением этой проблемы. У меня есть ListView, и я пытался найти, сколько я прокрутил, чтобы прокрутить что-то еще по отношению к нему и вызвать эффект параллакса. Вот мое решение:

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

Я создал свой собственный OnScrollListener, где метод onScrollPositionChanged будет вызываться каждый раз при вызове onScroll. Но этот метод будет иметь доступ к вычисленному значению, представляющему сумму, которую прокрутила ListView.

Чтобы использовать этот class, вы можете установитьOnClickListener в новый OnScrollPositionChangedListener и переопределить метод onScrollPositionChanged.

Если вам нужен метод onScroll для других вещей, вы можете переопределить это, но вам нужно вызвать super.onScroll, чтобы корректно работать onScrollPositionChanged.

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

Я столкнулся с аналогичной проблемой: мне захотелось поместить вертикальную поисковую строку в текущее прокручиваемое значение ListView . Поэтому у меня есть собственное решение, подобное этому.

Первый class

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

Затем используйте его в Основной деятельности, как это.

 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 adapter = new ArrayAdapter(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); } } 

в приложении Gradle

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

В XML-макете

            1            

background xml

      

заполнить xml

     

прогресс xml

        

thumb xml

      

в дополнение к ответу @jaredpetker . ListView не удерживает все элементы в своем прокрутке, поэтому вам нужно использовать только «видимую» часть списка. Когда вы прокручиваете вниз, верхние элементы сдвигаются и отображаются как новые элементы. То, как происходит преобразованиеView (это не пустой элемент для заполнения, это сдвинутый элемент, который не входит в «видимую» часть списка. Поэтому вам нужно знать, сколько элементов было перед видимой частью, умножить их на ListItemHeight и добавить headerHeight, thes how вы можете получить реальное абсолютное смещение в прокрутке. Если u получил не заголовок, позиция 0 будет listItem, поэтому вы можете упростить 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; } 
  • Множественный выбор в пользовательском ListView с CAB
  • Как получить выбранные элементы из списка Multi Select List
  • Как выделить строку в ListView в Android?
  • Push Listview, когда клавиатура появляется без настройкиPan
  • Как запустить onListItemClick в Listactivity с помощью кнопок в списке?
  • Android: реализация progressbar и «загрузка ...» для бесконечного списка, например Android Market
  • Отображение текущего выбора в списке
  • Как я могу обновить одну строку в ListView?
  • Android. Как работает метод notifyDataSetChanged () и ListViews?
  • Как реализовать поиск в CustomListView на основе classа classа POJO в Android?
  • Как изменить цвет линии разделителя Android ListView?
  • Interesting Posts

    как переопределить кнопку панели действий в андроиде?

    Передача реквизита от ребенка к родительской реакции навигации

    Требуется ли SqlCommand.Dispose (), если будет установлено связанное SqlConnection?

    Как я могу использовать обратную косую черту (\) в строке?

    Архивировать точку восстановления постоянно?

    Вызов глобальной переменной внутри модуля Typcript

    Печать реверса любой строки без использования какой-либо предопределенной функции?

    Как найти причину частого появления WHEA Uncorrectable error

    Различия в методах сравнения строк в C #

    Как найти все ссылки / страницы на веб-сайте

    Process.Close () не завершает созданный процесс, c #

    Dropbox выборочная синхронизация – возможно ли, чтобы новые папки, созданные на других устройствах, не были автоматически добавлены в папки синхронизации на текущем устройстве?

    Отправьте данные обратно в скрипт, который начал работу с помощью оболочки adb am start

    чтение строки из ifstream в строковую переменную

    Как я могу сделать запрос POST с помощью multipart / form-data с использованием Java?

    Давайте будем гением компьютера.