如果我在第一次点击后立即按两次按钮,我试图阻止活动加载两次 .
我有一个活动,点击按钮加载,比方说
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
现在因为要加载的活动具有网络调用,所以加载(MVC)需要一些时间 . 我确实显示了加载视图,但如果我在此之前按下按钮两次,我可以看到活动被加载两次 .
有谁知道如何防止这种情况?
18 回答
您可以覆盖startActivityForResult并使用实例变量:
在按钮的事件侦听器中,禁用该按钮并显示另一个活动 .
覆盖
onResume()
以重新启用该按钮 .将其添加到
Androidmanifest.xml
中的Activity
定义中...你可以像这样使用意图标志 .
它只会使一个活动在历史堆栈的顶部打开 .
由于SO不允许我评论其他答案,我不得不用新答案污染这个帖子 .
“活动打开两次”问题的常见答案以及我对这些解决方案的体验(Android 7.1.1):
禁用启动活动的按钮:工作但感觉有点笨拙 . 如果您有多种方法在应用程序中启动活动(例如操作栏中的按钮和单击列表视图中的项目),则必须跟踪多个GUI元素的启用/禁用状态 . 例如,在列表视图中禁用单击的项目并不是很方便 . 所以,不是一个非常普遍的方法 .
launchMode = "singleInstance":不使用startActivityForResult(),使用startActivity()中断导航,不建议Android驱动程序文档使用常规应用程序 .
launchMode = "singleTask":不使用startActivityForResult(),不建议Android驱动程序文档使用常规应用程序 .
FLAG_ACTIVITY_REORDER_TO_FRONT:休息按钮 .
FLAG_ACTIVITY_SINGLE_TOP:无效,活动仍然打开两次 .
FLAG_ACTIVITY_CLEAR_TOP:这是唯一一个为我工作的人 .
编辑:这是用startActivity()开始活动 . 使用startActivityForResult()时,我需要设置FLAG_ACTIVITY_SINGLE_TOP和FLAG_ACTIVITY_CLEAR_TOP .
假设@wannik是正确的,但如果我们有多个按钮调用同一个动作监听器,我在开始下一个活动之前几乎同时点击两个按钮...
所以如果你有一个字段
private boolean mIsClicked = false;
并且在监听器中是好的:并且
onResume()
我们需要返回状态:What's the deifference between my and @wannik's answer?
如果在其调用视图的侦听器中将enabled设置为false,则仍将启用使用相同侦听器的其他按钮 . 所以为了确保侦听器的动作没有被调用两次,你需要有一些全局禁用侦听器的所有调用(如果它是新实例或没有,则永远不要)
What is the difference between my answer and others?
他们正在以正确的方式思考,但他们并没有考虑将来返回到调用活动的同一个实例:)
使用singleInstance可以避免活动调用两次 .
我认为你正在以错误的方式解决问题 . 通常,活动在其任何启动生命周期方法(
onCreate()
,onResume()
等)中制作长时间运行的Web请求是一个坏主意 . 实际上,这些方法应该仅用于实例化和初始化您的活动将使用的对象,因此应该相对较快 .如果您需要执行Web请求,请在新启动的活动的后台线程中执行此操作(并在新活动中显示加载对话框) . 后台请求线程完成后,它可以更新活动并隐藏对话框 .
这意味着您的新活动应立即启动并防止双击 .
希望这可以帮助:
startActivity(intent)
这只对我有用对于这种情况,我将分别使用manifest.xml中的两个中的一个,
singleTask
或者活动的onResume()
和onDestroy()
方法中的一个标志 .对于 first 解决方案:我更喜欢使用
singleTask
作为清单中的活动而不是singleInstance
,因为使用singleInstance
我发现在某些情况下,活动为自己创建一个新的单独实例,导致在两个单独的应用程序窗口中在bcakground中运行的应用程序以及额外的内存分配当用户打开应用视图以选择要恢复的某个应用时,会导致非常糟糕的用户体验 . 因此,更好的方法是在manifest.xml中定义活动,如下所示:您可以查看活动启动模式here .
对于 second 解决方案,您只需定义静态变量或首选变量,例如:
从另一方面想要启动此活动时,只需检查:
其他非常简单的解决方案,如果你不想使用
onActivityResult()
是禁用按钮2秒(或你想要的时间),是不理想的,但可以部分解决问题是在某些情况下代码很简单:只需在按钮onClick方法中维护一个标志:
public boolean oneTimeLoadActivity = false;
如果您正在使用onActivityResult,则可以使用变量来保存状态 .
由于在事件上返回了请求代码,因此也会按下后退按钮 .
添加:
AndroidManifest.xml中的activity标记内部解决了这个问题 .
使用
flag
变量将其设置为to true
,检查其是否为真仅return
否则执行活动调用 .您还可以使用setClickable(false)执行活动调用
你也可以尝试一下