我有一个带有提交按钮的Android应用程序。按提交将表单数据保存到解析云中,然后用另一个替换当前片段:
submitAnswerBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String answer = answerET.getText().toString();
ParseUser currentUser = ParseUser.getCurrentUser();
Answer newAnswer = new Answer(answer, qid, currentUser);
newAnswer.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
});
}
});
我注意到如果我快速按两次提交按钮,我可能会崩溃应用程序。崩溃后,我在我的解析表中看到两次表单数据。
防止双重提交的最佳做法是什么?如果两次提交点击之间的时间少于3秒,我一直在考虑不坚持:
DateTime lastTimestamp = null;
public void onClick(View v) {
DateTime currentTimestamp = DateTime.now();
if(lastTimestamp == null)
lastTimestamp = currentTimestamp;
DateTime betweenClicks = currentTimestamp - lastTimestamp;
lastTimestamp = currentTimestamp;
// if a click happened within 3 seconds of the last one, show error and dont save again
if(0 < betweenClicks <= 3 seconds)
// show error dialog here
return;
String answer = answerET.getText().toString();
// rest of the code(save into parse)
这对我的解决方案并不重要,但是调试器显示崩溃是由于getFragmentManager()第二次返回null,为什么第二次返回null?如果我正常提交,请以与工作正常相同的方式提交另一个答案。
答案 0 :(得分:4)
我不认为getSupportFragmentManager()
返回null。我认为你的getActivity()
根据你说崩溃发生的位置返回null。
第一次提交时,您将从堆栈中弹出片段。这意味着Fragment
将与Activity
分离。因此,getActivity()
将返回null。
要解决此问题,只需执行以下操作:
Activity act = getActivity();
if (act == null) {
// already popped from the stack so no need to do it again.
return;
}
act.getSupportFragmentManager().popBackStack()
防止点击的另一种方法是,只需在第一次点击后立即停用按钮,即可致电setEnabled(false)
或setClickable(false)
。一旦你确认它已被保存,你就可以重新启用它(在这种情况下你不会立即离开,这不会是一个问题)。
答案 1 :(得分:2)
我怀疑第二次返回null的是getActivity()。一旦调用了popBackStack(),Fragment将与Activity分离,因此稍后对getActivity()的调用将返回null。
答案 2 :(得分:2)
对一个容易出问题的问题过于思考 - 一旦点击该按钮,我应该删除它并显示加载消息。我仍然不知道片段管理器为什么会快速点击无效; popbackstack删除了这个片段,但fragmentmanager仍然可以有内存。