Как правильно использовать TextSwitcher в ListView?

Мой TextSwitcher для каждой записи в ListView должен отображать первое значение ( text1 ), а затем другое значение ( text2 ), затем первое значение снова и так далее. Это должно произойти только в том случае, если text2 не пуст. В противном случае текст1 всегда должен отображаться (без каких-либо изменений и анимации).

Я создал Runnable() , который изменяет логическую переменную ( time2 ), а затем вызывает items.notifyDataSetChanged() . Он работает так, как ожидалось, и в результате setViewValue() для моего ListView .

Вот код:

 items.setViewBinder(new SimpleCursorAdapter.ViewBinder() { @Override public boolean setViewValue(View view, Cursor cursor, int columnIndex) { int viewId = view.getId(); switch(viewId) { case R.id.timetext: TextSwitcher itemTime = (TextSwitcher) view; if (itemTime.getChildCount() != 2) { itemTime.removeAllViews(); itemTime.setFactory(new ViewSwitcher.ViewFactory() { @Override public View makeView() { TextView t = new TextView(MyActivity.this); t.setTextSize(18); t.setTypeface(null, Typeface.BOLD); t.setTextColor(Color.WHITE); return t; } }); itemTime.setAnimateFirstView(true); itemTime.setInAnimation(AnimationUtils.loadAnimation(MyActivity.this, R.anim.push_up_in)); itemTime.setOutAnimation(AnimationUtils.loadAnimation(MyActivity.this, R.anim.push_up_out)); } if (!text2.equals("")) { if (!time2) { itemTime.setText(text1); } else { itemTime.setText(text2); } } else { itemTime.setCurrentText(text1); } return true; } return false; } } ); 

Он работает почти так, как ожидалось. С одним незначительным элементом – при отображении текста2 он сначала меняет отображаемое значение на какое-то другое значение (из другой записи!), А затем воспроизводится анимация. Изменение текста2 на текст1 происходит правильно.

Я понимаю, что причина в следующем: перед отображением text2 все виды itemTime удаляются и, следовательно, воссоздаются, и поэтому некоторое другое значение отображается на секунду. Но почему это показывает ценность из какой-то другой записи?

Фактически text2 и text1 являются значениями из базы данных, например. text2 = cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_TIME_2)) , возможно, что-то здесь не так, и setViewValue вызывал неправильные параметры?

Upd. Text1 и text2 считываются из базы данных в setViewValue . Вот пример полного кода:

 itemTime.setText(cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_CLOSE_TIME_1)) + " - " + cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_OPEN_TIME_1))); 

Solutions Collecting From Web of "Как правильно использовать TextSwitcher в ListView?"

Я думаю, что я вижу, что здесь происходит, и это связано с тем, как работает ListView.

ListView перерабатывает все свои представления изнутри, так что у вас есть только столько просмотров, которые могут отображаться на экране. Однако это также означает, что когда вы привязываете значения к представлению в методе setViewValue, вам не всегда предоставляется представление, которое ранее находилось в той же позиции в списке.

Скажем, у вас есть три элемента списка: itemA, itemB, itemC в этом порядке. Каждый из них сначала содержит text1, text2 и text3.

Когда вы вызываете items.notifyDataSetChanged() , ListView перерабатывает все эти элементы списка, но это похоже на то, что вы можете получить новый порядок itemC, itemA, itemB; И текст затем будет читать text3, text1, text2.

В результате, когда вы меняете текст первого элемента списка на «text2», вы фактически увидите «text3» вместо «text2» вместо перехода от «text1» в «text2», как вы ожидаете.

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

Я советую вам использовать ViewFlipper вместо TextSwitcher . Причина этого заключается в том, что после того, как вы добавили TextView в свой ViewFlipper , вы можете просто установить интервал флип, а затем начать перелистывание, и он сделает это автоматически для вас.

Проще всего это:

 /* Add your items to your ViewFlipper first */ myViewFlipper.setFlipInterval(1000); //time in millseconds myViewFlipper.startFlipping(); 

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

Как приятный сюрприз, вы можете заметить, что ваша проблема уходит, потому что вам не нужно снова перечитывать все, что есть у вас из БД, и уменьшает шансы на путаницу item1 и item2, так как вам нужно будет только прочитать их один раз, когда Строка создается в вашем ListView

Только мои 2 цента.

Дайте мне знать, как это происходит.

Являются ли text1 и text2 в файле ресурсов (res / values ​​/ strings.xml)? Если это так, Android иногда путает переменные. Просто запуск Project > Clean в этом проекте может решить проблему.

Это сработало для меня:

 myViewFlipper.setFlipInterval(1000); myViewFlipper.startFlipping();