Android DialogFragment getActivity() 为 null

Den*_*Loh 2 android nullpointerexception android-alertdialog dialogfragment

我正在尝试创建一个对话框,在用户注销之前向用户显示倒计时。超时是从另一个活动设置的。

我写了以下代码:

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;

public class SessionInactivityDialog extends DialogFragment {

    public void setInactivityTimeout(long timeout) {
        Resources res = getActivity().getResources();
        String text = String.format(res.getString(R.string.iminent_logout_text), (timeout / 1000));
        ((AlertDialog)getDialog()).setMessage(text);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setTitle(R.string.iminent_logout);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                SessionActivity activity = (SessionActivity)getActivity();
                activity.resetTimer();
            }
        });

     return builder.create();
    }

}
Run Code Online (Sandbox Code Playgroud)

使用以下几行调用该对话框:

private void showIminentLogoutDialog(long timeout) {
    mInactivityDialog.show(getFragmentManager(), TAG);
    mInactivityDialog.setInactivityTimeout(timeout);
}
Run Code Online (Sandbox Code Playgroud)

即使超时是在对话框打开后设置的,getActivity()setInactivityTimeout()is中null

如何正确获取fragment中的资源?

kco*_*ock 5

DialogFragment.show()是异步的——DialogFragment实际上并没有立即显示——它被发送到消息队列的末尾。我建议提供超时值作为参数,然后将其onCreateDialog()与标题一起设置。例如:

public class SessionInactivityDialog extends DialogFragment {
    public static final String EXTRA_TIMEOUT = "timeout";

    public static SessionInactivityDialog newInstance(long timeout) {
        Bundle args = new Bundle();
        args.putLong(EXTRA_TIMEOUT, timeout);
        SessionInactivityDialog dialog = new SessionInactivityDialog();
        dialog.setArguments(args);
        return dialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final SessionActivity activity = (SessionActivity) getActivity();
        final long timeout = getArguments().getLong(EXTRA_TIMEOUT);
        final String msg = activity.getString(R.string.imminent_logout_text, (timeout / 1000));

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(R.string.imminent_logout);
        builder.setMessage(msg);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                activity.resetTimer();
            }
        });
        return builder.create();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用以下方式显示它:

SessionInactivityDialog.newInstance(timeout)
                       .show(getFragmentManager(), TAG);
Run Code Online (Sandbox Code Playgroud)

我还建议为对话框创建一个接口来与活动进行通信,而不是添加直接依赖项SessionActivity(这样您就可以在任何活动中重用它,只要它实现您的接口)。