尝试从片段中的 AlertDialog 打开 Activity
Trying to open an Activity from an AlertDialog in a Fragment
因此,在对片段内部启动的 AlertDialog
进行一些确认后,我尝试打开一个新的 Activity。
我的问题是上下文。我已经尝试使用 getActivity()
和 getContext()
,但都无济于事。这个想法是通过此对话框确认用户操作(特别是删除帐户,因此将用户带到特定的 Activity 很重要),并在确认后启动 IntroActivity。
这是我的内容 AlertDialog
class:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view = inflater.inflate(R.layout.layout_excluir_usuario_dialog, null);
dialog.setView(view)
.setTitle("Deseja mesmo excluir a sua conta?")
.setMessage("Excluir a sua conta resultará na eliminação completa dos seus dados do Salarium.")
.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
FirebaseUser usuario = autenticacao.getCurrentUser();
usuario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(dialog.getContext(), "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity().getApplicationContext(), IntroActivity.class);
startActivity(intent);
} else {
Toast.makeText(dialog.getContext(), "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
}
}
});
}
});
return dialog.create();
}
最后,无论我选择何种上下文方法组合,我都会遇到 NullPointerExceptions。
Process: com.filipewilliam.salarium, PID: 19838
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
at com.filipewilliam.salarium.fragments.ExcluirUsuarioDialog.onComplete(ExcluirUsuarioDialog.java:55)
at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)```
我认为这可能是问题所在 (Why does AlertDialog.Builder(Context context) only accepts Activity as a parameter?):
getApplicationContext()
returns 您的应用程序的上下文,这与您的活动上下文基本相同 - "mostly" 是让您失望的原因。
细节尚不清楚,但这是一个广泛遇到的问题,典型的答案是使用将警报写入屏幕的上下文。
请注意,这不是 getApplicationContext()
返回的那个。
AlertDialog
会在单击按钮时自动关闭对话框 - 即,当您的 setPositiveButton
OnClickListener
触发时。关闭对话框后,DialogFragment
会自动删除。
因为您正在进行异步工作,所以您的结果returns 关闭对话框并删除 DialogFragment。届时,预计 dialog.getContext()
将为 null,DialogFragment 上的 getContext()
也将为 null。
无法将 AlertDialog 的行为更改为仅在异步回调完成后关闭,但您可以在开始异步工作之前保留 Context 并在异步调用完成时使用它:
@Override
public void onClick(DialogInterface dialogInterface, int i) {
final Context context = getContext();
autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
FirebaseUser usuario = autenticacao.getCurrentUser();
suario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(context, "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(context, IntroActivity.class);
startActivity(intent);
} else {
Toast.makeText(context, "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
}
}
});
请注意,这有一个缺点:如果您的 Activity 在异步工作 运行 时被销毁,您将继续保留对旧 Activity 的引用,而不是让它立即被垃圾收集。假设您的任务不会花费很长时间,这对您来说可能不是问题。
函数中的 getActivity()
方法 Returns null
。初始化对话框时,您应该传递 Activity 上下文。
你可以像答案一样做 here
获得战斗上下文(Activity 继承自上下文)后,您可以创建意图并从中启动 Activity
因此,在对片段内部启动的 AlertDialog
进行一些确认后,我尝试打开一个新的 Activity。
我的问题是上下文。我已经尝试使用 getActivity()
和 getContext()
,但都无济于事。这个想法是通过此对话框确认用户操作(特别是删除帐户,因此将用户带到特定的 Activity 很重要),并在确认后启动 IntroActivity。
这是我的内容 AlertDialog
class:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view = inflater.inflate(R.layout.layout_excluir_usuario_dialog, null);
dialog.setView(view)
.setTitle("Deseja mesmo excluir a sua conta?")
.setMessage("Excluir a sua conta resultará na eliminação completa dos seus dados do Salarium.")
.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
FirebaseUser usuario = autenticacao.getCurrentUser();
usuario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(dialog.getContext(), "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity().getApplicationContext(), IntroActivity.class);
startActivity(intent);
} else {
Toast.makeText(dialog.getContext(), "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
}
}
});
}
});
return dialog.create();
}
最后,无论我选择何种上下文方法组合,我都会遇到 NullPointerExceptions。
Process: com.filipewilliam.salarium, PID: 19838
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
at com.filipewilliam.salarium.fragments.ExcluirUsuarioDialog.onComplete(ExcluirUsuarioDialog.java:55)
at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)```
我认为这可能是问题所在 (Why does AlertDialog.Builder(Context context) only accepts Activity as a parameter?):
getApplicationContext()
returns 您的应用程序的上下文,这与您的活动上下文基本相同 - "mostly" 是让您失望的原因。
细节尚不清楚,但这是一个广泛遇到的问题,典型的答案是使用将警报写入屏幕的上下文。
请注意,这不是 getApplicationContext()
返回的那个。
AlertDialog
会在单击按钮时自动关闭对话框 - 即,当您的 setPositiveButton
OnClickListener
触发时。关闭对话框后,DialogFragment
会自动删除。
因为您正在进行异步工作,所以您的结果returns 关闭对话框并删除 DialogFragment。届时,预计 dialog.getContext()
将为 null,DialogFragment 上的 getContext()
也将为 null。
无法将 AlertDialog 的行为更改为仅在异步回调完成后关闭,但您可以在开始异步工作之前保留 Context 并在异步调用完成时使用它:
@Override
public void onClick(DialogInterface dialogInterface, int i) {
final Context context = getContext();
autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
FirebaseUser usuario = autenticacao.getCurrentUser();
suario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(context, "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(context, IntroActivity.class);
startActivity(intent);
} else {
Toast.makeText(context, "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
}
}
});
请注意,这有一个缺点:如果您的 Activity 在异步工作 运行 时被销毁,您将继续保留对旧 Activity 的引用,而不是让它立即被垃圾收集。假设您的任务不会花费很长时间,这对您来说可能不是问题。
函数中的 getActivity()
方法 Returns null
。初始化对话框时,您应该传递 Activity 上下文。
你可以像答案一样做 here
获得战斗上下文(Activity 继承自上下文)后,您可以创建意图并从中启动 Activity