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 で行われているという事実が問題ではないことを願っています。
この部分は、「アンドロイド開発者」が私のような初心者がこれを正しく行うのを助けるためのものです。最初の一連のイベント:
1. コールバックで Bluetooth を介してデータが受信される
2. データのタイプが正しい場合、メイン アクティビティ (UI スレッド) で BroadcastReceiver が通知され、そこからパラメータを設定するルーチンが呼び出されるWaveFormView の が View クラスを拡張し、メイン アクティビティで onCreateDialog(id) コールバックを呼び出す ShowDialog(id) が呼び出されます。
3. 次に、invalidate() を呼び出します。
4. ダイアログがポップアップし、グラフが描画されます。
5. ShowDialog(id) への後続のすべての呼び出しは、onCreateDialog(id) をバイパスします。
それは機能しますが、パラメータに関係なく、領域全体が常に無効になります。ここにもユーザーイベントはありません。あなたの例から私が思いつくことができる最高のものは、showDialog(id) の後に自分自身を呼び出す代わりに onShow() に無効化を配置する次のとおりです。
@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が唯一の方法です。
ところで、我慢してくれてありがとう!