我想使用DialogFragment
显示自定义对话框。但是,在我需要修改它们之前,我无法初始化布局视图。
这是我的DialogFragment
课程。
public class RemoteProgressDialog extends DialogFragment {
private TextView lockProgress;
private TextView foldProgress;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Dialog_NoActionBar);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.remote_progress_dialog, null);
lockProgress = (TextView) view.findViewById(R.id.lock_progress);
return view;
}
public void lockFinished() {
lockProgress.setCompoundDrawables(
null,
getResources().getDrawable(R.drawable.icn_mycar_sunroof_open),
null, null);
// TODO: remove
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
showLockProgress(false);
dismissDialogIfNeeded();
}
public void showLockProgress(boolean show) {
lockProgress.setVisibility(show ? View.VISIBLE : View.GONE);
}
private void dismissDialogIfNeeded() {
if (lockProgress.getVisibility() == View.GONE) {
// TODO: add conditions
dismiss();
}
}
我在Fragment
中显示对话框,如下所示:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
progressDialog = new RemoteProgressDialog();
}
@Override
public boolean onLongClick(View v) {
progressDialog.show(getFragmentManager(), REMOTE_PROGRESS_DIALOG);
progressDialog.showLockProgress(true);
return true;
}
起初我尝试使用AlertDialog.Builder
构建对话框,但我得到NullPointerException
,因为在onCreateDialog()
之前未执行showLockProgress()
方法,因此lockProgress
为空。好吧,我还是不需要AlertDialog
,所以我最终使用这种方法,希望它有助于解决问题。
不幸的是它没有帮助。调用方法lockProgress
时,showLockProgress()
仍为null。我在onCreate()
的{{1}}和onCreateView()
方法以及托管DialogFragment
的{{1}}中设置了断点。 onAttach()
中的那个会被触发,因此应创建Fragment
的实例,但似乎不会调用onAttach()
或DialogFragment
。当我长按按钮时,会调用onCreate()
,但onCreateView()
仍然为空。
为什么在创建对话框实例时或在我调用showLockProgress()
方法后立即初始化我的视图?
答案 0 :(得分:2)
所以我想问题是你的public
方法在onCreate
等之前调用,因为在show
调用DialogFragment
之后,初始化对话框需要时间,它是视图和所有变量。因此,在我看来,您可以采用正确的方式处理此方法,只需创建一个boolean
变量,然后在显示DialogFragment
之前设置该变量。像这样:
public class RemoteProgressDialog extends DialogFragment {
private boolean mShowText = false; // default value
private TextView lockProgress;
public void setShowText(boolean showText){
this.mShowText = showText;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.remote_progress_dialog, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
// initialise your views here
lockProgress = (TextView) view.findViewById(R.id.lock_progress);
showLockProgress(mShowText);
}
public void showLockProgress(boolean show) {
lockProgress.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
您可以在显示Dialog
:
progressDialog.show(getFragmentManager(), REMOTE_PROGRESS_DIALOG);
progressDialog.setShowText(true);
因此,这样您就无法获得NullPointerException
,并且您可以确定,根据您设置的boolean
,您TextView
中的RemoteProgressDialog
将被隐藏或在初始化时可见。
希望这有帮助!
答案 1 :(得分:1)
<强>问题:强>
我认为问题在于,在创建并显示dialogFragment之前尝试showLockProgress
,这会导致在分配之前尝试访问lockProgress
。
@Override
public boolean onLongClick(View v) {
progressDialog.show(getFragmentManager(), REMOTE_PROGRESS_DIALOG);
progressDialog.showLockProgress(true);
return true;
}
执行该代码时会发生以下情况:
show
方法“是一种方便显式创建事务,使用给定标记向其添加片段并提交” - 它创建一个事务来添加一个事务片段并提交它。commit
方法实际上会在将来的某个时间点调度事务的提交。 onLongClick
方法在主线程上执行,因此事务的执行提交(以及片段创建)计划在此方法完成后的某个时刻发生。但在其中,您尝试访问stil-not-initialized成员lockProgress
(在showLockProgress
内)。<强>解决方案:强>
使用Android-Developer的idea并实现一个布尔成员,可用于在创建视图后显示(或不显示)进度(例如,在onViewCreated
中)。这样你只能从外面告诉DialogFragment它应该显示进度(或不显示进度),但让它在内部处理“when”和“how”。