2

我不明白为什么 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是唯一的方法。

顺便说一句,谢谢你忍受我!

4

2 回答 2

0

我认为这取决于您究竟对什么进行了失效。如果您调用失效的视图没有处理矩形失效,则发生默认失效。

无论如何,如果你想改变行为,你可以自己改变。对于“onDraw”方法,使用下面的代码来获取无效的矩形:

public class InvalidateTestActivity extends Activity
{
    static class CustomView extends ImageView

    {

        public CustomView(Context context)
        {
            super(context);
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            final Rect r = canvas.getClipBounds();
            Log.d("DEBUG", "rectangle of invalidation:" + r);
            super.onDraw(canvas);
        }

    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        CustomView customView = new CustomView(this);
        customView.setLayoutParams(new FrameLayout.LayoutParams(200, 200));
        customView.setBackgroundColor(0xffff0000);
        customView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v)
            {
                v.invalidate(new Rect(0, 0, 49, 49));
            }
        });
        setContentView(customView);
    }
}
于 2012-05-02T23:39:17.650 回答
0

如果您启用了硬件加速,它看起来只会使整个视图无效......

视图组:

public final void invalidateChild(View child, final Rect dirty) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null && attachInfo.mHardwareAccelerated) {
        // HW accelerated fast path
        onDescendantInvalidated(child, child);
        return;
    }
于 2021-07-12T19:51:51.973 回答