在Handler中设置TextView的文本性能差

5
由于Android不支持显示日期的星期几,因此我在我的布局中添加了一个TextView。
在DatePicker上,我设置了一个onDateChangedListener。当日期更改时,我确定星期几,然后通过Handler设置它,以确保在UI线程上完成:
// this is being called when the date changes on the DatePicker
public void onDateChanged(DatePicker view, final int year,
                final int monthOfYear, final int dayOfMonth) {
    String dayOfTheWeek = null;

    // some code here to set the 'dayOfTheWeek' string

    h.sendMessage(h.obtainMessage(0, dayOfTheWeek));
}

final Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        dayOfWeekTextView.setText((String)msg.obj);
    }
};

我的问题是:当我在小部件中滚动日期时(Android 4.0 UI),它不够流畅!我检查了问题所在,发现问题不在我确定String的方式上,而是在Handler中的setText()。如果将该部分注释掉,一切都正常。即使在那里设置一个硬编码文本(dayOfWeekTextView.setText("SOMETHING');)也会出现同样的问题。它会抖动DatePickersetText()真的是如此重要的操作吗?Wunderlist显示了一周的工作日,它运行得很顺畅,但我只是找不到他们是如何做到的。
我只在我的HTC One X上进行了测试。 有人有想法吗?

编辑:

我发现为什么Wunderlist中很流畅!我正在使用与他们相同的DialogFragment。您可以在对话框上设置标题,这是Wunderlist使用的而不是TextView。因此,我将使用它(看起来更好;))

所以当执行“getDialog().setTitle(dayOfWeek)”时没有问题。问题仍然存在:为什么在UI线程上setText如此缓慢...?

4个回答

4

性能差可能是由布局重新计算导致的。如果TextView的宽度为wrap-content,则每次文本更改时,都会更新布局。 尝试修复TextView的宽度。


3

解决方案 一个非常简单粗暴的解决方案是创建7个TextView并切换它们之一的可见性。在一周不会被延长到8天的情况下,这种方法应该具有更好的性能。


另外,这可能是由于你的TextView的布局参数引起的。你可能需要给它一些额外的空间,或者换句话说,setText不应该带来布局。我不确定是否发生了这种情况。


是的,这是一种可能性,但不是我的问题的答案。感谢您提出的解决方案,我很感激。所以你认为可能是布局参数的问题?所以(我现在无法检查,在我的日常工作中;)我可能需要检查layout_width是否设置为match_parent? - Boy
是的,也许match_parent不会导致整个层次结构重新绘制。 - Sherif elKhatib
2
非常感谢!确实是“match_parent”起了作用!我还学会了一个新词(incurred) :) - Boy

0

我尝试使用您提到的类似“处理程序”方法来实现相同的功能,结果表明它非常出色且响应迅速。

请尝试此代码:

final DatePicker dp = (DatePicker)findViewById(R.id.datePicker1);

        dp.init(2012, 6, 17, new OnDateChangedListener() {

            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear,
                    final int dayOfMonth) {

                handler.post(new Runnable() {

                    @Override
                    public void run() {

                        TextView tv = (TextView) findViewById(R.id.textView1);

                        // some code here to set the 'dayOfTheWeek' string


                        tv.setText(Integer.toString(dayOfTheWeek));   // (if you want to set a number of day instead of its name)

                                           //  OR

                        tv.setText(dayOfTheWeek);   

                    }
                });

            }
        });

这里的窍门是使用包装类 Integer 将 int 值转换为字符串。如果传递原始的 'int',它将抛出一个 资源未找到 异常。

我认为你在宽度上使用了“match_parent”,这对我有帮助(我将把它设置为答案)。无论如何,感谢你的努力回答! - Boy

0

尝试使用这个格式:

t1.setText(""+string_name);

我在设置 TextView 和 EditText 中的文本时使用了这种格式


1
这样做实际上会更慢(或者在最好的情况下相同),因为(String)msg.obj需要进行类型转换。而msg.obj已经是String类型,所以不需要进行转换。 - andr
当我尝试使用格式setText(str_name)时,它对我无效。这就是为什么我使用setText(""+str_name),这对我很有效。 - user1954492
是的,我尝试过了(不理解为什么多一步会加速)。你说的“它对我没用”是指性能问题还是根本无法运行? - Boy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接