c# - Toast 显示不止一次

标签 c# .net xamarin.android

我正在开发适用于 Android 的 QR 阅读器应用程序。该应用程序的主要目的是使用手机摄像头读取二维码。如果用户未使用该应用程序,则相机会在一定时间后停止(为此使用 Timer)以防止电池消耗并使手机振动,显示带有指示用户的消息的 toast 按下按钮重新激活相机,然后继续他的工作。

问题是,当事件第一次被触发时,一切都像我预期的那样工作,但如果它被第二次触发,Toast 将显示两次,如果事件被触发 N 号,则依此类推的时间。

此解决方法背后的逻辑如下:

“恢复”相机功能的按钮逻辑:

btnEncenderCamara.Click += (sender, e) => {
            camara.Start(lectorQR.Holder);
            btnEncenderCamara.Enabled = false;
            timerToDisableCamera.Interval = 6000;
            timerToDisableCamera.Elapsed += new ElapsedEventHandler(timerElapsed);
            timerToDisableCamera.Start();
        };

这里是定时器的事件逻辑:

protected void timerElapsed(object sender, ElapsedEventArgs e) {
        try
        {
            timerToDisableCamera.Stop();
            RunOnUiThread(() => {
                Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
                vibrator.Vibrate(1000);
                camara.Stop();
                btnEncenderCamara.Enabled = true;
                Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
            });
        }
        catch (Exception ex)
        {

            throw;
        }
    }

我需要找到如何避免在停止相机的事件被触发后多次显示 Toast。

最佳答案

请注意,在您的 btnEncenderCamara.Click 事件中,您如何在每次触发 btnEncenderCamara.Click 时为 timerToDisableCamera.Elapsed 事件订阅一个新委托(delegate)。

因此,在每次后续调用 btnEncenderCamara.Click 时,您的 timerElapsed 方法将被调用不止一次。

解决此问题的一种方法是在调用 timerToDisableCamera.Stop() 后取消订阅 timerElapsed 方法中的委托(delegate),如下所示:

protected void timerElapsed(object sender, ElapsedEventArgs e) {
        try
        {
            timerToDisableCamera.Stop();

            timerToDisableCamera.Elapsed -= new ElapsedEventHandler(timerElapsed);

            RunOnUiThread(() => {
                Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
                vibrator.Vibrate(1000);
                camara.Stop();
                btnEncenderCamara.Enabled = true;
                Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
            });
        }
        catch (Exception ex)
        {

            throw;
        }
    }

或者,您可以重构您的代码以仅初始化一次计时器,这将保持您的逻辑精简,如下所示:

// I'm assuming this method is an entry point for initialization in your Android activity.
void OnLoad()
{
    // I'm assuming timerToDisableCamera already have an instance of Timer, otherwise you will get a NullReferenceException.
    timerToDisableCamera.Interval = 6000;
    timerToDisableCamera.Elapsed += new ElapsedEventHandler(timerElapsed);

    // And also assuming that btnEncenderCamara is already an instance of Button.
    btnEncenderCamara.Click += (sender, e) => {
        camara.Start(lectorQR.Holder);
        btnEncenderCamara.Enabled = false;
        timerToDisableCamera.Start();
    };
}

protected void timerElapsed(object sender, ElapsedEventArgs e)
{
    try
    {
        timerToDisableCamera.Stop();

        RunOnUiThread(() => {
            Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
            vibrator.Vibrate(1000);
            camara.Stop();
            btnEncenderCamara.Enabled = true;
            Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
        });
    }
    catch (Exception ex)
    {
        throw;
    }
}

关于c# - Toast 显示不止一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54382505/

相关文章:

c# - 为我的 API 实现 OAuth 2.0 身份验证

c# - 如何在不删除文件的情况下清除文本文件?

c# - 在 Xamarin 中设置窗口 KeepScreenOn 标志

c# - TaskCompletionSource 和 dismiss 导致多个自定义警报对话框没有出现

c# - 调用包含#的号码

c# - 从异常中提取类和文件名

c# - 在winform中创建一个本地数据库并在后台从服务器获取数据

c# - 有没有办法找到特定层中的每个 RigidBody?

c# - 如何通过 lambda 表达式传递属性?

c# - 如何访问实现IEnumerable的对象中的第一个元素