gpt4 book ai didi

Android:View如何绘制组件?

转载 作者:行者123 更新时间:2023-11-30 03:23:05 25 4
gpt4 key购买 nike

安卓问题:当我将文本设置为 View 时, View 何时会更新 UI?这是我的案例 1:

for(int i=0;i< 2000; i++){
aTextView.setText("a"+i);
}

aTextView 是从 TextView 扩展而来的 MyTextView。我将 onDraw 改写为:

public static int counterP = 0;

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
counterP++;
Log.d("MYButton", "onDraw: " + counterP);
}

从日志中可以看出,打印的counterP不是后继的。在循环中,onDraw方法只被调用了2-4次。

我又做了一个测试,案例2:

boolean notInit = true;
List<String> cmdList = null;
long stSelfRefresh = 0;
String contentStr;
TextView selfTv;

public void onSelfRefreshTv(View v) {
if (cmdList == null || cmdList.isEmpty()) {
Log.e(TAG, "empty now, reset");
notInit = true;
}
if (notInit) {
cmdList = new ArrayList<String>();
for (int i = 0; i < 2000; i++) {
cmdList.add("a" + i);
}
stSelfRefresh = SystemClock.uptimeMillis();
notInit = false;
selfTv = (MyTextView) findViewById(R.id.mytv);
}
contentStr = cmdList.remove(0);
Log.d(TAG, "contentStr = " + contentStr);
selfTv.setText(contentStr);

if (!cmdList.isEmpty()) {
if (!mHandler.sendEmptyMessage(99)) {
Log.e(TAG, "SKIP my self");
}
} else {
Log.d(TAG, "Cost time: " + (SystemClock.uptimeMillis() - stSelfRefresh));
}
}

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 99:
onSelfRefreshTv(null);
break;
default:
break;
}
}
};

情况 2 的结果是 counterP 被打印出来。 1-2000。

不知道为什么每次都更新textView?你有什么想法吗?

提前致谢。

******添加案例 3 ***********

for(int i=0;i< 2000;i++){ 
contentStr = cmdList.remove(0);
mHandler.sendEmptyMessage(100);

}

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 100:
selfTv.setText(contentStr);
break;
default:
break;
}
}
};

******案例 3 结束**********案例3的测试结果与案例1类似。

最佳答案

看起来您正在 UI Thread 上运行您的代码。

这意味着:只要你的代码在运行,绘图代码就不能运行。 onDraw() 在循环完成计数后调用,并且只有最后一个值实际绘制在显示器上。
就这么简单。

如果你想在显示器上计数,你可以使用 AsyncTask 将计数部分移动到非 UI Thread:

    new AsyncTask<Void,Integer, Void>() {
@Override
protected Void doInBackground(Void... voids) {
for (int i =0; i<2000; i++) {
publishProgress(i);
}
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
aTextView.setText("a"+values[0]);
}
};

你的第二种情况是这样的:

  1. 您准备包含所有 2000 个元素的列表。
  2. 将列表的第一个元素设置为 TextView 并从列表中删除该项。
  3. 一旦系统认为合适,就向自己发送消息以在 UI Thread 上运行。
  4. 放开对 UI 线程的控制。
  5. 您的代码实际上已经完成,系统调用onDraw()
  6. 来自 4 的消息得到处理,您从 2 重新开始。

您会看到系统在循环中间控制了 UI Thread。这就是它明显计数的原因。

案例 3 不同于案例 2:

您正在循环发送 2000 条消息,而没有让系统处理它。

关于Android:View如何绘制组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18760679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com