【问题标题】:Android: discard events perceived after a button clickAndroid:丢弃按钮点击后感知到的事件
【发布时间】:2013-06-01 16:22:27
【问题描述】:

按下按钮后,应用程序会尝试将数据发送到服务器。如果连接处于活动状态,则立即发送数据,但如果链接断开,系统将尝试发送 x 秒。实际上,在那段时间里,界面(故意)被阻塞(按钮被点亮以突出当前操作)。问题在于,如果用户开始按下其他按钮,则会听到事件,并且当连接变为活动状态时,它会执行与这些事件相关的所有操作。
如何预防?
如何防止这种情况如何防止与其他按钮相关的每个事件被处理? 任何建议将不胜感激。

编辑 我已经尝试在按下按钮时检查标志,不幸的是,当重新设置标志时,所有事件都被捕获并执行:

public void onClick(View v) {                   
    switch(v.getId())
    {

    case R.id.button1:  //when sendData() is trying to send the message, I don't want to that this code is executed
       if(flagConf  == 1)  
       {
                ...do something...
       }
       break;
    case R.id.buttonConfirm:

        if(myFlag  == 1)    //to avoid multiple touch of this button
        {
            ...do something...
            myFlag = 0;
            sendData(); 
            if(dataSent)     
             ...do something...
            else
            ...do something...
            myFlag = 1;  //I set this flag to 1 because, if message is not sent, the user have to re-pressed the buttonConfirm and try again
        }     
     break;
    }
 }

在其他按钮监听器上:

谢谢

【问题讨论】:

    标签: android events button event-handling


    【解决方案1】:

    在处理数据时,您可以简单地使用设置为 boolean = true; 之类的标志。然后签入onClick中的每个Button

    public void onClick(View v)
    {
         if (!sending)
         {
             // do stuff
         }
    }
    

    如果sendingtrue 那么Button 将什么也不做。请记住在处理完数据或其他内容后将flag 设置回false。完成后,您也可以使用 buttonName.setEnabled(false);then back totrue`。

    旁注:如果这个操作需要很长时间(可能超过一两秒),我会劝阻不要让他们做任何事情,因为人们已经变得非常没有耐心。没有人愿意坐着看一个旋转的圆圈几秒钟。但是,如果您选择这样做,那么您可能需要显示一些消息,以便他们知道为什么 Buttons 不起作用

    【讨论】:

    • 不幸的是我已经这样做了,但是所有其他事件都被捕获了......当连接打开时,所有事件都被处理了。
    • 嗯...这没有任何意义,除非您的代码中发生了其他事情。您已经在onClick 中尝试了上述方法,并且代码仍然运行?如果是这种情况,那么您可能需要发布一些代码,以便我们可以确切地看到发生了什么
    • 从该代码看来,无论数据发送的结果如何,myFlag 都被设置为 1。您应该仅在您的 sendData() 方法成功执行后进行设置
    • 是的,我将 myFlag 设置为 1,因为如果消息未发送,用户必须按下按钮尝试再次发送。
    • 没关系,您只是希望禁用其他Buttons? flagConf 是什么,在哪里设置?如果您在此处设置断点并且它 == 1,那么它将不会运行该代码。也许我不理解你
    【解决方案2】:

    我遇到了类似的问题。有一个很好的解决方法。

    我与服务器的连接是通过扩展AsyncTask 的类完成的。这样,每次我按下按钮时,我都会检查任务是否正在运行。如果不是,它将生成一个新任务并执行该任务。

    public void onClick(View v) {
        if (updateThread == null){
    
            updateThread = new UpdateThreadClass();
            updateThread.execute();
        }
    }
    

    然后像这样创建 AsyncTask:

       public class UpdateThreadsClass extends AsyncTask<String, Void, Boolean> {
        @Override
        protected Boolean doInBackground(String... params) {
    
            // Your code
        }
    
        @Override
        protected void onPostExecute(final Boolean success) {
    
            // Execute after completing the connection
        }
    }
    

    将变量 updateThread 声明为全局变量,然后就可以了。

    如果您愿意,您可以在任务完成之前和之后通过更改可见性(.setVisibility(View.VISIBLE).setVisibility(View.Gone) 内的 .setVisibility(View.Gone))来激活 XML 上的进度条,或者您可以执行按钮也是如此。

    编辑

    您可以将进度条放在XML 中,如下所示:

    <ProgressBar
                android:id="@+id/loading_screen"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true" 
                android:layout_centerVertical="true"
                android:gravity="center_vertical|center_horizontal"
                android:visibility="gone"/>
    

    然后点击按钮后,就像loadingScreen = (ProgressBar) findViewById(R.id.loading_screen)一样,设置可见性可见。

    【讨论】:

    • 感谢您的回答。不幸的是,我不能使用 AsyncTask。如果不使用,可以加进度条吗?
    • 是的,你可以!让我编辑答案,然后添加 sn-p。
    • 谢谢,这对我很有用!
    • 非常感谢,很好的提示。我已经接受了一个答案,所以我给你一个 +1。
    • 没问题!很高兴它有帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    相关资源
    最近更新 更多