我不明白为什么 invalidate(Rect) 会使整个区域无效。该区域分为 5 个部分,每个部分都绘制了一个折线图。每个部分包含 100 分。当数据到达时间 tn 到 tn+100 时,我调用 invalidate(new Rect(left, top, right bottom)) ,其中 top 是屏幕顶部的高度(但数值低于底部)。这会调用 onDraw() 方法。绘制从 tn 到 tn+100 的区域,但擦除区域 tn-100 到 tn 中先前绘制的段。它永远这样继续下去。每个无效仅绘制正确的区域(因为这是我拥有的唯一数据),但所有先前绘制的数据都被删除。所以我得到了一个游行部分!
换句话说,如果我调用 invalidate() 或 invalidate(Rect),我会得到相同的行为。
我假设 Rect() 的参数是像素,并且正在根据正在绘制它的 AlertDialog 窗口的高度和宽度获取值。
希望最终减少“Rect()”的区域,这样我就可以模拟实时绘图,并且只使时间步 t 无效到 t+1 而不是区域。
我一定是在做一些愚蠢的事情。
我希望它在 AlertDialog 中完成的事实不是问题。
这部分是为了帮助“android 开发者”帮助像我这样的菜鸟做对。首先是事件序列:
1. 在回调中通过蓝牙接收数据
2. 如果是正确类型的数据,则向主活动(UI 线程)中的 BroadcastReceiver 发出信号,并从那里调用一个设置参数的例程WaveFormView 扩展 View 类,然后调用 ShowDialog(id) 调用主活动中的 onCreateDialog(id) 回调。
3. 然后我调用 invalidate()。
4. 弹出对话框,然后绘制图形。
5. 所有后续对 ShowDialog(id) 的调用都会绕过 onCreateDialog(id)
这可行,但无论参数如何,整个区域始终无效。这里也没有用户事件。从您的示例中,我能想到的最好的方法是在 onShow() 中放置 invalidate 而不是在 showDialog(id) 之后调用自己
@Override
protected Dialog onCreateDialog(int id)
{
Log.d(TAG, "Alert Dialog 'onCreateDialog' method has been called with id " + id);
Builder bldr = new AlertDialog.Builder(this);
AlertDialog alert = bldr.setView(waveForm).setNegativeButton("Dismiss " + id,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
}).create();
// I tried adding this and invalidating here worked only first pass
alert.setOnShowListener(
new DialogInterface.OnShowListener()
{
@Override
public void onShow(DialogInterface dialog)
{
// call to invalidate
waveForm.drawArea();
}
});
//alert.getWindow().setLayout(alert.getWindow().getAttributes().width, alert.getWindow().getAttributes().height / 2);
alert.getWindow().setLayout(waveForm.getCurrentWidth(), waveForm.getCurrentHeight());
return alert;
}
但是 onShow() 不会被调用。
调用 showDialog 的主要活动中的方法是
private void displayRtsa(int[] rtsaReceived)
{
// rtsaReceived[0] has the agentsink hash code
int agent = rtsaReceived[0];
// rtsaReceived[1] has the index of the RtsaData object updated
int index = rtsaReceived[1];
TreeMap<Integer, RtsaData[]> agentRtsa = BluetoothPanService.getAgentRtsaMap();
RtsaData[] rtsaDataValues = agentRtsa.get(agent);
int dialogId = 0;
synchronized(dialogIds)
{
int i = 0;
if(dialogIds.containsKey(agent + index) == false)
{
for(i = 0; i < dialogIds.size(); i++)
{
if(dialogIds.containsValue(i) == false)
{
break;
}
}
dialogIds.put(agent + index, i);
}
dialogId = dialogIds.get(agent + index);
}
final int id = dialogId;
Log.d(TAG, "Dialog id being shown = " + dialogId);
waveForm.setPeriod(rtsaDataValues[index].getPeriod());
waveForm.setMaxMin(rtsaDataValues[index].getMinValue(), rtsaDataValues[index].getMaxValue());
waveForm.setColor(Color.argb(255, 255, 200, 0));
waveForm.setData(rtsaDataValues[index].getData());
waveForm.setTitle(rtsaDataValues[index].getType());
showDialog(id);
// invalidate
// waveForm.drawArea(); (try to do in onCreateDialog callback)
}
这可能是一个完全错误的方法。可能openGl是唯一的方法。
顺便说一句,谢谢你忍受我!