如何在按下按钮时阻止活动加载两次

tej*_*jas 82 android onclick button android-activity

如果我在第一次点击后立即按两次按钮,我试图阻止活动加载两次.

我有一个活动,点击按钮加载,比方说

 myButton.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
       //Load another activity
    }
});
Run Code Online (Sandbox Code Playgroud)

现在因为要加载的活动具有网络调用,所以加载(MVC)需要一些时间.我确实显示了加载视图,但如果我在此之前按下按钮两次,我可以看到活动被加载两次.

有谁知道如何防止这种情况?

Awa*_*riq 138

将其添加到您的Activity定义中AndroidManifest.xml......

android:launchMode = "singleTop"
Run Code Online (Sandbox Code Playgroud)

  • 这可以防止活动的两个实例存在,但它不会阻止代码错误地运行两次.尽管投票率较低,但接受的答案更好. (17认同)
  • 这是错误的,它使活动永远不会存在两次,即使在不同的任务中也是如此.正确的方法是`android:launchMode ="singleTop"`,它可以在不破坏Android多任务处理的情况下实现效果.该文档指出大多数应用程序不应使用`singleInstance`选项. (17认同)
  • 还有什么可能??? 你必须要有一种方法来实现线程以获得一个平滑的应用程序...尝试它dude ..;)只需将所有当前代码放在一个方法中,并从你编写的同一个地方的单独线程调用该方法它早些时候...它几乎不会增加五到六行代码.. (2认同)

wan*_*nik 55

在按钮的事件侦听器中,禁用该按钮并显示另一个活动.

    Button b = (Button) view;
    b.setEnabled(false);

    Intent i = new Intent(this, AnotherActitivty.class);
    startActivity(i);
Run Code Online (Sandbox Code Playgroud)

覆盖onResume()以重新启用按钮.

@Override
    protected void onResume() {
        super.onResume();

        Button button1 = (Button) findViewById(R.id.button1);
        button1.setEnabled(true);
    }
Run Code Online (Sandbox Code Playgroud)


Car*_*doL 35

你可以像这样使用意图标志.

Intent intent = new Intent(Class.class);    
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
activity.startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

它只会使一个活动在历史堆栈的顶部打开.

  • 这个答案与最受欢迎的答案相结合似乎效果最好.在Activity的清单中使用这个标志:`android:launchMode ="singleTop"`,这样它就可以解决,而不必将标志添加到每个Intent. (4认同)
  • 这应该是正确的android-way答案 (3认同)
  • 在startActivityForResult的情况下不起作用 (2认同)

And*_*oid 21

由于SO不允许我评论其他答案,我不得不用新答案污染这个帖子.

"活动打开两次"问题的常见答案以及我对这些解决方案的体验(Android 7.1.1):

  1. 禁用启动活动的按钮:工作但感觉有点笨拙.如果您有多种方法在应用程序中启动活动(例如,操作栏中的按钮和单击列表视图中的项目),则必须跟踪多个GUI元素的启用/禁用状态.例如,在列表视图中禁用单击的项目并不是很方便.所以,不是一个非常普遍的方法.
  2. launchMode ="singleInstance":不使用startActivityForResult(),使用startActivity()中断导航,不建议Android驱动程序文档使用常规应用程序.
  3. launchMode ="singleTask":不使用startActivityForResult(),不建议用于Android清单文档的常规应用程序.
  4. FLAG_ACTIVITY_REORDER_TO_FRONT:休息按钮.
  5. FLAG_ACTIVITY_SINGLE_TOP:不工作,活动仍然打开两次.
  6. FLAG_ACTIVITY_CLEAR_TOP:这是唯一一个为我工作的人.

编辑:这是用startActivity()开始活动.使用startActivityForResult()时,我需要设置FLAG_ACTIVITY_SINGLE_TOP和FLAG_ACTIVITY_CLEAR_TOP.

  • 我正在使用“FLAG_ACTIVITY_REORDER_TO_FRONT”,它工作正常,返回按钮也正常。“返回按钮”究竟是什么意思?你能澄清一下吗? (2认同)

Sir*_*rst 5

假设@wannik是正确的,但如果我们有多个按钮调用同一个动作监听器,我在开始下一个活动之前几乎同时点击两个按钮...

所以如果你有领域private boolean mIsClicked = false;和听众是好的:

if(!mIsClicked)
{
    mIsClicked = true;
    Intent i = new Intent(this, AnotherActitivty.class);
    startActivity(i);
}
Run Code Online (Sandbox Code Playgroud)

onResume()我们需要返回的状态:

@Override
protected void onResume() {
    super.onResume();

    mIsClicked = false;
}
Run Code Online (Sandbox Code Playgroud)

我和@wannik的答案之间的差异是什么?

如果在其调用视图的侦听器中将enabled设置为false,则仍将启用使用相同侦听器的其他按钮.所以为了确保侦听器的动作没有被调用两次,你需要有一些全局禁用侦听器的所有调用(如果它是新实例或没有,则永远不要)

我和其他人的答案有什么区别?

他们正在以正确的方式思考,但他们并没有考虑将来返回到调用活动的同一个实例:)


小智 5

使用singleInstance避免活动调用两次。

<activity
            android:name=".MainActivity"
            android:label="@string/activity"
            android:launchMode = "singleInstance" />
Run Code Online (Sandbox Code Playgroud)


Shy*_*dda 5

它只对我有用 startActivity(intent)

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Run Code Online (Sandbox Code Playgroud)