내 레이아웃을 사용하여 DialogFragment를 만들려고합니다.
저는 몇 가지 다른 접근 방식을 보았습니다. 때때로 레이아웃은 OnCreateDialog에서 다음과 같이 설정됩니다. (Mono를 사용하고 있지만 Java에 다소 익숙해졌습니다)
public override Android.App.Dialog OnCreateDialog (Bundle savedInstanceState)
{
base.OnCreateDialog(savedInstanceState);
AlertDialog.Builder b = new AlertDialog.Builder(Activity);
//blah blah blah
LayoutInflater i = Activity.LayoutInflater;
b.SetView(i.Inflate(Resource.Layout.frag_SelectCase, null));
return b.Create();
}
이 첫 번째 접근 방식은 저에게 효과적입니다 … 사용하고 싶을 때까지 findViewByID.
약간의 인터넷 검색 후 재정의와 관련된 두 번째 접근 방식을 시도했습니다.OnCreateView
그래서 OnCreateDialog
레이아웃을 설정 한 두 줄을 주석 처리 한 다음 다음을 추가했습니다.
public override Android.Views.View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.Inflate(Resource.Layout.frag_SelectCase, container, false);
//should be able to use FindViewByID here...
return v;
}
나에게 멋진 오류를 제공합니다.
11-05 22:00:05.381: E/AndroidRuntime(342): FATAL EXCEPTION: main
11-05 22:00:05.381: E/AndroidRuntime(342): android.util.AndroidRuntimeException: requestFeature() must be called before adding content
난 당황해.
답변
이 첫 번째 접근 방식은 FindViewByID를 사용하고 싶을 때까지 저에게 효과적입니다.
에서 findViewById()
반환 한 View로 범위 를 지정하지 않았다고 생각합니다 inflate()
.
View view = i.inflate(Resource.Layout.frag_SelectCase, null);
// Now use view.findViewById() to do what you want
b.setView(view);
return b.create();
답변
다음 코드에서 동일한 예외가 발생했습니다.
public class SelectWeekDayFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage("Are you sure?").setPositiveButton("Ok", null)
.setNegativeButton("No way", null).create();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.week_day_dialog, container, false);
return view;
}
}
DialogFragment에서 onCreateView 또는 onCreateDialog 중 하나만 재정의하도록 선택해야합니다 . 둘 다 재정의하면 “콘텐츠를 추가하기 전에 requestFeature ()를 호출해야합니다”라는 예외가 발생합니다.
중대한
완전한 답변은 @TravisChristian 코멘트를 확인하십시오. 그가 말했듯이 실제로 둘 다 재정의 할 수 있지만 대화보기를 이미 만든 후보기를 확장하려고하면 문제가 발생합니다.
답변
아래 코드는 Google 가이드에서 가져온 것이므로 대답은 onCreateDialog ()에서 당신의 것을 좋아할 수 없다는 것입니다. 대화 상자를 얻으려면 super.onCreateDialog ()를 사용해야합니다.
public class CustomDialogFragment extends DialogFragment {
/** The system calls this to get the DialogFragment's layout, regardless
of whether it's being displayed as a dialog or an embedded fragment. */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
return inflater.inflate(R.layout.purchase_items, container, false);
}
/** The system calls this only when creating the layout in a dialog. */
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example, the dialog includes a
// title by default, but your custom layout might not need it. So here you can
// remove the dialog title, but you must call the superclass to get the Dialog.
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
답변
다음은 Dialog Fragment에서 findViewById를 사용하는 예입니다.
public class NotesDialog extends DialogFragment {
private ListView mNotes;
private RelativeLayout addNote;
public NotesDialog() {
// Empty constructor required for DialogFragment
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.note_dialog, null);
mNotes = (ListView) view.findViewById(R.id.listViewNotes);
addNote = (RelativeLayout) view.findViewById(R.id.notesAdd);
addNote.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
getDialog().dismiss();
showNoteDialog();
}
});
builder.setView(view);
builder.setTitle(bandString);
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
getDialog().dismiss();
}
}
);
return builder.create();
}
답변
@Xavier Egea가 말했듯이 onCreateView ()와 onCreateDialog ()가 모두 구현 된 경우 “콘텐츠를 추가하기 전에 requestFeature ()를 호출해야합니다”충돌이 발생할 위험이 있습니다. 이는 해당 조각을 대화 상자로 표시 () 할 때 onCreateDialog ()와 onCreateView ()가 모두 호출되기 때문입니다 (왜, 모르겠습니다). Travis Christian이 언급했듯이 onCreateDialog ()에서 대화 상자가 생성 된 후 onCreateView ()의 inflate ()가 충돌의 원인입니다.
이 두 함수를 모두 구현하지만이 충돌을 피하는 한 가지 방법 : getShowsDialog ()를 사용하여 onCreateView () 실행을 제한합니다 (따라서 inflate ()가 호출되지 않음). 이렇게하면 DialogFragment를 대화 상자로 표시 할 때 onCreateDialog () 코드 만 실행되지만 DialogFragment가 레이아웃에서 조각으로 사용될 때 onCreateView () 코드를 호출 할 수 있습니다.
// Note: if already have onCreateDialog() and you only ever use this fragment as a
// dialog, onCreateView() isn't necessary
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (getShowsDialog() == true) { // **The key check**
return super.onCreateView(inflater, container, savedInstanceState);
} else {
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_alarm_dialog, null);
return configureDialogView(view);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Return custom dialog...
Dialog dialog = super.onCreateDialog(savedInstanceState); // "new Dialog()" will cause crash
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_alarm_dialog, null);
configureDialogView(view);
dialog.setContentView(view);
return dialog;
}
// Code that can be reused in both onCreateDialog() and onCreateView()
private View configureDialogView(View v) {
TextView myText = (TextView)v.findViewById(R.id.myTextView);
myText.setText("Some Text");
// etc....
return v;
}
답변
제목 및 닫기 버튼과 같은 대화 상자 속성에 쉽게 액세스하고 싶지만 자체 레이아웃도 사용하려는 경우 onCreateDialog를 재정의 할 때 Builder와 함께 LayoutInflator를 사용할 수 있습니다.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Message!")
.setTitle(this.dialogTitle)
.setView(inflater.inflate(R.layout.numpad_dialog, null))
.setPositiveButton(R.string.enter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Clicked 'Okay'
}
})
.setNegativeButton(R.string.dismiss, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Clicked 'Cancel'
}
});
return builder.create();
}