Intereting Posts

SmoothScrollToPosition () только прокручивает часть в Android ICS?

В Gingerbread у меня не было проблем с использованием smoothScrollToPosition (), чтобы прокручивать несколько десятков элементов за раз. После того как мой Nexus S был обновлен до Ice Cream Sandwich, я заметил, что независимо от того, что я вставляю в smoothScrollToPosition (), он будет прокручивать только пару сотен пикселей в любом направлении, а затем останавливаться.

Это известная проблема с ICS? Я заметил это с Galaxy Nexus. Я просмотрел несколько других вопросов и попробовал несколько разных трюков, например, отключить вызовы notifyDataSetChanged () и опубликовать smoothScrollToPosition () как задержанную runnable, но, к сожалению, он не хочет прокручивать больше, чем Сто пикселей или около того до остановки. 🙁

Кажется, проблема связана с продолжительностью, необходимой для завершения анимации, та же проблема присутствует с smoothScrollBy (int distance, int duration), при беглом взгляде smoothScrollToPosition () – это дружественная оболочка вокруг smoothScrollBy (), которая делает много беготня. SmoothScrollBy (), в свою очередь, притворяется «бегущим жестом», как если бы пользователь совершил движение.

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

Трудность для ребят Android заключается в определении того, сколько для перемещения каждым вызовом run () для достижения требуемого смещения, потому что ячейки ListView (дети) полностью динамичны по высоте, поэтому они не могут просто выполнить простой расчет расстояния, Видимая детская высота неизвестна им. Это та же самая причина, по которой полоса прокрутки Android может изменяться по мере прокрутки, она должна лучше понять, насколько она должна быть основана на том, что она сейчас видит.

В любом случае, это не поможет вам решить эту проблему, но кому-то это может показаться интересным 🙂

Если вы знаете, что у вас есть статические высоты ящиков, вы можете написать свой собственный метод, чтобы рассчитать расстояние и длительность, чтобы перейти к smoothScrollBy () самостоятельно и иметь статическое количество времени для перемещения расстояния X. Если вы этого не сделаете, вам будет достаточно использовать широко распространенное решение bigstones, которое действительно работает из-за высокого SCROLL_DURATION в 1000 мс. Вы можете взять версию ICS и изменить этот атрибут, а не использовать версию 2.2, которая не является основной причиной.

Вы также можете адаптировать эти runnables своим собственным алгоритмом, это не должно быть слишком сложно настроить.

Это то, что я сделал для решения проблемы. По сути, мы хотим продолжать называть smoothscrolling до тех пор, пока вы не достигнете нужного элемента (в этом случае я просто хочу прокрутить вверх, что является элементом 0).

//There is a known bug where smoothScrollToPosition(..) may not reach the top, //if the list is very large, keep scrolling until you reach the top element newsFeed.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if(firstVisibleItem != 0) { newsFeed.smoothScrollToPosition(0); } else { //We are done newsFeed.setOnScrollListener(null); } } }); newsFeed.smoothScrollToPosition(0); 

Если ваша цель – прокрутить вверх, рассмотрите возможность использования smoothScrollToPositionFromTop(0,0) . вместо.

Поскольку ListView использует метод getChildCount (), чтобы получить счет позиции в исходном коде AbsListView.java. Но в ListView метод getChildCount () не может правильно подсчитать. Возможно, вам следует использовать метод setSelection ().

У меня также проблема с ICS.

У меня есть активность списка сообщений чата, каждый раз, когда я отправляю сообщение, мне нужно прокручивать список вниз до нуля. Поэтому после того, как я вызвал notifyDataSetChanged (), я назвал метод smoothScrollToPosition (). В других версиях сборки для Android он работает хорошо. Но на ICS это очень странно. Если мой список находится внизу, я проверил 3 случая. Если я добавлю один новый элемент в список, он не будет прокручиваться. Если я добавлю два новых элемента в список -> он будет прокручиваться хорошо. И если я прокручу список в несколько пикселей, после добавления одного нового элемента, он будет хорошо прокручиваться. После многого поиска и теста Google я чувствую беспомощность по этому поводу. Наконец, каждый раз, когда я устанавливаю данные в listview, я добавляю пустой вид (1px) в последнюю позицию, хотя это не очень хороший метод, но он работает для меня.