2011-01-11 3 views
13

나는 사용자로부터 텍스트 데이터를 얻을 수 있도록 EditText를 포함하는 커스텀 다이얼로그를 만들고있다.대화 상자 문제 : 콘텐츠를 추가하기 전에 requestFeature()를 호출해야합니다.

final EditText newKey = (EditText) findViewById(R.id.dialog_result); 
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this); 
keyBuilder 
.setCancelable(false) 
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     Log.v("Dialog","New Key: "+newKey.getText().toString()); 
    } 
}) 
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
AlertDialog dialog = keyBuilder.create(); 
dialog.setTitle("Decryption Failed"); 
dialog.setContentView(R.layout.decrypt_failed_dialog); 
dialog.show(); 

그러나 나는 항상이 예외를 가진다 :

01-11 18:49:00.507: ERROR/AndroidRuntime(3461): android.util.AndroidRuntimeException: requestFeature() must be called before adding content 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181) 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at com.android.internal.app.AlertController.installContent(AlertController.java:199) 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at android.app.AlertDialog.onCreate(AlertDialog.java:251) 

... 
dialog.show()의 라인에서

. 이걸 없애기 위해 내가 무엇을해야합니까?

답변

34

대화 상자를 만들기 전에 사용자 정의보기를 설정해야합니다. AlertDialog으로 제공된 기본 양수 및 음수 버튼을 사용하는 경우 setContentView() 대신 setView(View)을 사용해야합니다.

final EditText newKey = (EditText) findViewById(R.id.dialog_result); 
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this); 
keyBuilder 
.setCancelable(false) 
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     Log.v("Dialog","New Key: "+newKey.getText().toString()); 
    } 
}) 
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
keyBuilder.setTitle("Decryption Failed"); 
keyBuilder.setView(getLayoutInflater().inflate(R.layout.decrypt_failed_dialog, null)); 
AlertDialog dialog = keyBuilder.create(); 
dialog.show(); 
+2

다른 사람이 코드를 비교할 필요없이 다르게 수행 된 것을 알아낼 수 있도록 주석을 추가하는 것이 좋을 것입니다. – codinguser

+0

당신은 맞습니다 ... 지금 당장 시간이 없습니다. 더 정확한 답변을 편집 하시겠습니까? – Cristian

+3

감사! "... 당신은 setContentView() ... 대신 setView (View)를 사용해야합니다.":) –

4

이미 표시된 대화 상자를 반환하지 않았는지 확인하십시오. 예를 들어, ProgressDialog은 몇 가지 매개 변수를 사용하고 ProgressDialog을 반환하는 편리한 정적 메서드 show()을가집니다. 그 방법을 사용할 수없고 그 결과로 ProgressDialog을 반환 할 수 없다는 것을 알게된다. 왜냐하면 OS가 그것을 보여 주려고 할 때 (이미 보여 졌기 때문에),이 동일한 예외를 던질 것이기 때문이다.

주의 : 위의 동작은 Android 에뮬레이터에서 경험할 수 있지만 예외가 발생하지 않았으며 2.2 Droid Incredible에서 정상적으로 작동했습니다.

2

나는 비슷한 문제가있었습니다. 하지만 IME 용 대화 상자가 표시되었습니다. AlertDialog 대신 Dialog로 전환하고 create를 생략하면 프로그램이 나에게 도움이되었습니다.

-3

이 문제를 해결하는 정확한 방법 :

requestFeature(int)Window하는 방법입니다. 이 클래스를 가져와야합니다 (android.view.Window).

그리고 AlertDialog.Builder 개체의 창을 가져와야합니다. 그런 다음 requestFeature(int)으로 전화하십시오. 입력 매개 변수는 Window의 상수입니다.

keyBuilder.getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

4

나는 년 전에이 우연히 이상한 코드를 사용하는 방식을 수정했습니다. 다시 말하지만, 제가 작업하고있는 앱에는 휴대 전화에서는 정상적으로 표시되어야하지만 태블릿에서는 대화 상자에 표시되어야하는 부분이 있습니다. 나는 이런 식으로 해결 :

public class MyDialogFragment extends DialogFragment { 
    private View mLayout; 
    private ViewGroup mContainer; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     mContainer = container; 
     if (getShowsDialog()) { 
      // one could return null here, or be nice and call super() 
      return super.onCreateView(inflater, container, savedInstanceState); 
     } 
     return getLayout(inflater, container); 
    } 

    private View getLayout(LayoutInflater inflater, ViewGroup container) { 
     mLayout = inflater.inflate(R.layout.my_layout, container, false); 
     return mLayout; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return new AlertDialog.Builder(getContext()) 
       .setPositiveButton(R.string.ok, null) 
       .setNegativeButton(R.string.cancel, null) 
       .setNeutralButton(R.string.filter_clear_selection, null) 
       .setView(getLayout(LayoutInflater.from(getContext()), mContainer)) 
       .create() 
      ; 
    } 
} 

이 날 (레이아웃)에있는 정상적인 조각으로 내 조각을 추가 할 수 있지만 또한 자율적으로 실행 대화 상자로 표시 할 수 있습니다.

3

DialogFragment을 사용할 때이 문제가 특별히있는 사람들을위한 것입니다.

내 경우에는 DialogFragment 클래스를 잘못 확장했기 때문에 이런 일이 발생했습니다. onCreateView()에 대한보기를 반환했으며 또한 onCreateDialog()에 사용자 지정 대화 상자를 반환했습니다.문서 상태 :

당신은 당신이 어떤 상황에서 대화로 표시 에 UI의 조각을하고자하는 UI 디자인을 가질 수 있지만, 다른 사람의 전체 화면 또는 내장 된 조각 (아마에 따라 같은 장치 이 큰 화면이든 작은 화면이든). DialogFragment 클래스는 여전히 을 임베딩 가능한 조각으로 동작 할 수 있으므로이 유연성을 제공합니다.

그러나이 경우에는 에 AlertDialog.Builder 또는 다른 Dialog 객체를 사용하여 대화 상자를 빌드 할 수 없습니다. DialogFragment를 임베드 가능하게하려면 레이아웃에서 대화 상자의 UI를 정의한 다음 onCreateView() 콜백에 레이아웃을로드해야합니다.

onCreateDialog()에 아무 것도 만들지 않아서 문제가 해결되었습니다 (수퍼 클래스 구현 만 반환).

관련 문제