我是Android开发中的新手,因此我坚持使用DialogFragment生命周期行为。我希望我的DialogFragment能够代表身份验证对话框,其中包含登录名和密码TextViews以及两个按钮。它似乎创造了两次。我试图记录生命周期,所以它的工作方式如下:
onAttach
onCreate
onCreateDialog
onCreateView
onActivityCreated
onViewStateRestored
onStart
onResume
onSaveInstanceState
onDetach
onAttach
onCreateDialog
onCreateView
onActivityCreated
onViewStateRestored
onAttach
onCreate
onCreateDialog
onCreateView
onActivityCreated
onViewStateRestored
onStart
onStart
onResume
onResume
onDetach
onSaveInstanceState
onDetach
onAttach
onCreateDialog
onCreateView
onActivityCreated
onViewStateRestored
onAttach 1
onCreate
onCreateDialog
onCreateView
onActivityCreated
onViewStateRestored
onStart
onStart
onResume
onResume
onDetach
问题是,当我尝试旋转设备时,savedInstanceState设置为null,因为当它不是onAttach并且其他方法被调用时。这是我的DialogFragment代码:
public class SignInDialog extends DialogFragment implements View.OnClickListener{
private SignInDialogListener mSignInDialogListener;
private EditText mUsername;
private EditText mPassword;
private Button mReset;
private Button mLogin;
private Integer count=0;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_sign_in, container);
Log.v("test","onCreateView");
this.getDialog().setTitle(R.string.login);
mUsername = (EditText) view.findViewById(R.id.username);
mPassword = (EditText) view.findViewById(R.id.password);
mReset = (Button) view.findViewById(R.id.reset_button);
mLogin = (Button) view.findViewById(R.id.login_button);
setRetainInstance(true);//helps to avoid Dialog creates many times on rotation
mReset.setOnClickListener(this);
mLogin.setOnClickListener(this);
return view;
}
public void onAttach(Activity context) {
super.onAttach(context);
count++;
Log.v("test","onAttach "+count);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mSignInDialogListener = (SignInDialogListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
+ " must implement AuthenticationDialogListener");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("login",mUsername.getText().toString());
outState.putString("password",mPassword.getText().toString());
Log.v("test","onSaveInstanceState");
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
Log.v("test","onViewStateRestored");
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Log.v("test","onCreateDialog ");
return super.onCreateDialog(savedInstanceState);
}
public static SignInDialog newInstance() {
return new SignInDialog();
}
public void onClick(View v) {
if (v.equals(mLogin)) {
if (mPassword.getText().toString().length() < 1) {
Toast.makeText(getActivity(), R.string.invalid_password, Toast.LENGTH_SHORT).show();
return;
} else {
mSignInDialogListener.onSignInDialogLoginClicked(mUsername.getText().toString(),
mPassword.getText().toString());
this.dismiss();
}
} else if (v.equals(mReset)) {
mSignInDialogListener.onSignInDialogResetClicked(mUsername.getText().toString());
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.v("test","onActivityCreated ");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.v("test","onStart ");
super.onStart();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.v("test","onCreate ");
super.onResume();
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
Log.v("test","onResume ");
super.onResume();
}
@Override
public void onDetach() {
Log.v("test","onDetach ");
super.onDetach();
}
来自我创建DialogFragment
的活动的代码 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeActivity(savedInstanceState);
}
private void initializeActivity(Bundle savedInstanceState) {
mSignInDialog = new SignInDialog();
mSignInDialog.setCancelable(false);//to avoid back button pressed
mSignInDialog.show(getSupportFragmentManager(), "Login");
mToolbar = (Toolbar) findViewById(R.id.main_toolbar);
mSearchRecyclerView = (RecyclerView) findViewById(R.id.search_recycler_view);
mProgressBar = (ProgressBar) findViewById(R.id.search_progress_bar);
setSupportActionBar(mToolbar);
mSearchViewPresenter = new SearchViewPresenter(MainActivity.this);
}
答案 0 :(得分:0)
在this link中解释:
某些设备配置可能会在运行时更改(例如屏幕方向,键盘可用性和语言)。发生此类更改时, Android会重新启动正在运行的活动(调用onDestroy(),然后调用onCreate())。
因此,当您旋转屏幕时,将处理销毁活动的整个过程,然后重新创建。附加到激活的片段遵循相同的过程。
对于已保存的实例问题,您可以关注documentation。
答案 1 :(得分:0)
您可以检查您的片段是否已附加到当前片段管理器。如果已经添加,则可以关闭当前片段。
@Override
public void onAttach(Context context) {
super.onAttach(context);
Fragment loginFragment = getActivity().getFragmentManager().findFragmentByTag("Login");
if(loginFragment != null){
dismiss();
}
}
我假设你在活动
开始对话