如何在ListView中正确使用TextSwitcher?

时间:2011-05-23 18:44:51

标签: android sqlite android-listview

TextSwitcher中每条记录的ListView应显示第一个值( text1 ),然后显示另一个值( text2 ),然后是第一个值再一次等等。只有当 text2 不为空时才会发生这种情况。否则,应始终显示 text1 (不做任何更改和动画)。

我创建了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;
    }
  } );

它几乎按预期工作。使用一个小项 - 当应显示 text2 时,它会首先将显示值更改为其他值(来自另一个记录!),然后播放动画。 text2 更改为 text1 正确发生。

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

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

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

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

4 个答案:

答案 0 :(得分:4)

我知道这可能不会直接回答这个问题,但我会回复你关于创建Runnable()来为你做切换工作的评论,因为我怀疑它可能会弄乱你的数据(很难说你什么时候看不到完整的代码)。

我建议您使用ViewFlipper代替TextSwitcher。这样做的原因是,一旦您在TextView中添加了ViewFlipper,您就可以设置翻转间隔,然后开始翻转,它会自动为您完成。

这很简单:

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

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

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

中创建行时,它们会一次显示

只需2美分。

让我知道它是怎么回事。

答案 1 :(得分:2)

我想我知道这里发生了什么,这是因为ListView的工作方式。

ListView在内部回收其所有视图,以便您只创建可在屏幕上显示的视图。但是,这也意味着当您将值绑定到setViewValue方法中的视图时,并不总是给出之前在列表中位于相同位置的视图。

假设您有三个列表项:itemA,itemB,itemC。每个都分别包含text1,text2和text3。

当您致电items.notifyDataSetChanged()时,ListView会回收所有这些列表项,但感觉就像是,因此您可能会获得itemC,itemA,itemB的新订单;然后文本将读取text3,text1,text2。

因此,当您将第一个列表项的文本更改为“text2”时,您实际上会看到“text3”更改为“text2”而不是像“text1”那样从“text1”转换为“text2”期待。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

这对我有用:

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