如何在ListView中正确使用TextSwitcher?

ListView每条记录的TextSwitcher应显示第一个值( text1 ),然后显示另一个值( text2 ),然后再显示第一个值,依此类推。 只有当text2不为空时才会发生。 否则应始终显示text1 (不进行任何更改和animation)。

我创建了Runnable() ,它更改了布尔variables( 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; } } ); 

它几乎按预期工作。 使用一个次要项目 – 当应显示text2时,它首先将显示的值更改为其他值(来自另一个记录!),然后播放animation。 text2text1的更改正确发生。

我的理解原因如下 – 在显示text2之前, itemTime所有视图都被删除,因此它被重新创建,这就是为什么一些其他值被显示为秒的原因。 但为什么它显示其他记录的价值呢?

实际上text2text1是数据库中的值,例如。 text2 = cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_TIME_2)) ,可能,这里setViewValue用错误的参数调用了setViewValue

UPD。 在setViewValue从数据库中读取text1text2 。 以下是完整代码的示例:

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

我想我看到这里发生了什么,这是因为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 。 这样做的原因是,一旦你在ViewFlipper添加了TextView ,你就可以设置你的翻转间隔,然后开始翻转,它会自动为你做。

就这么简单:

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

在您描述的当前方法中,当您调用items.notifyDataSetChanged() ,会产生巨大的性能items.notifyDataSetChanged()因为您的数据库的所有项目都将被重新读取,并且您的列表将再次“重新绘制”。 只有当您的实际数据真正发生更改而不是使用它来切换您已有的文本并且不会从创建时间更改时,您才应该这样做。

令人惊讶的是,您可能会注意到您的问题消失了,因为您不必再​​次从您的DB中重新读取所有内容并减少混淆item1和item2的可能性,因为您只需要读取它们一次该行在ListView创建

只需2美分。

让我知道事情的后续。

text1和text2是否存储在资源文件中(res / values / strings.xml)? 如果是这样,Android有时会混淆variables。 只需在此项目上运行Project > Clean即可解决问题。

这对我有用:

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