Android : 대화 상자의 EditText가 소프트 키보드를 표시하지 않습니다.


82

그래서 일반적인 문제인 것 같습니다. 즉, 대화 상자의 EditText가 포커스를받을 때 표시되지 않는다는 것입니다. 나는 this thread , this one and this one (and more)와 같은 몇 가지 해결 방법을 보았지만 처음 에 이런 일이 발생 하는지에 대한 만족스러운 설명을 보지 못했습니다 .

나는 안드로이드가 내 자신을 만드는 것보다 EditTexts에 대한 자체 기본 동작을 사용하는 것을 훨씬 선호하지만, 모든 사람 (해당 스레드의)이 대화 상자의 EditText에 대한 기본 동작은 커서 만 제공하고 키보드를 제공하지 않는 것임을 인정한 것 같습니다. 왜 그럴까요?

기록을 위해, 이러한 해결 방법 중 어느 것도 나를 위해 작동하지 않는 것 같습니다. 내가 올 수 있었던 가장 가까운 방법은 키보드를 대화 상자 아래에 강제로 표시하는 것입니다 (InputMethodManager.toggleSoftKeyboard (*) 사용). 내 특정 구성은 API15이며 EditText는 AlertDialog 내 ListView의 바닥 글에 표시됩니다. EditText android : focusable = "true"가 설정되고 onFocusChangeListener 포커스 이벤트를 수신합니다.

편집하다:

요청한대로 여기에 제가 작업중인 특정 코드 스 니펫이 있습니다. 전체 레이아웃은 신경 쓰지 않지만이 특정 응용 프로그램에서는 대화 상자의 버튼을 누르면 EditText가 나타납니다 ( 액션 뷰 와 유사 ). 기본적으로 가시성이 "사라진"RelativeLayout에 포함됩니다.

 <RelativeLayout 
       android:id="@+id/relLay"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_centerVertical="true"
       android:visibility="gone"
       android:layout_marginTop="5dp"
       android:layout_marginBottom="5dp">

        <ImageButton
            android:id="@+id/cancelBut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:background="@color/transparent"
            android:src="@drawable/cancelButton" 
            android:layout_margin="5dp"/>

        <ImageButton
            android:id="@+id/okBut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/cancelBut"
            android:background="@color/transparent"
            android:src="@drawable/okButton"
            android:layout_margin="5dp" />

        <EditText 
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text"
            android:focusable="true"
            android:layout_toLeftOf="@id/okBut"/>
   </RelativeLayout>

이를 빌드하는 코드는 relativeLayout의 가시성을 "Visible"로 설정하고 다른 UI 요소를 숨 깁니다. 이것은 해야 글고 치기가 글고 내 경험을 바탕으로, 집중됩니다 때 키보드를 끌어하기에 충분. 그러나 어떤 이유로 이것은 사실이 아닙니다. 다음 onFocusChangeListener를 설정할 수 있습니다.

    edit_text.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // For whatever reason we need to request a soft keyboard.
                    InputMethodManager imm = (InputMethodManager)dlg.getWindow().getContext().getSystemService(_Context.INPUT_METHOD_SERVICE);
                    if(hasFocus)
                        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                    Log.v("DialogProblem", "Focus requested, " + (hasFocus?"has focus.":"doesn't have focus."));
                }
            }
        });

이 구성을 사용 하여 EditText를 처음 입력하면 onFocusChangedListener가 트리거되고 항상 다음과 같은 로그를 생성합니다.

Focus requested, has focus.
Focus requested, doesn't have focus.
Focus requested, has focus.

키보드가 표시되었다가 사라집니다. 아마도 두 번 토글하기 때문일 것입니다.하지만 계속 켜져 있는지 확인하더라도 대화 창 뒤에 있습니다 (회색으로 표시된 영역). 대화 상자를 닫지 않고는 액세스 할 수 없습니다. .

그게 내가 작업에 주위 작업이를받을 수 있습니다 비록 내가있어, 그 강조하고 싶습니다 말했다 주로 관심이 간단한 이유를 찾는 이유 글고 치기는 처음에 트리거되지 않습니다, 그리고 왜이 너무 평범한 것 같습니다!


관련 코드 스 니펫 (포커스 설정, 포커스 리스너 추가 등)을 게시 해 주시겠습니까?
Alexander Lucas

나는 할 수있다 (그리고 내가 컴퓨터로 돌아갈 때 그렇게 할 것이다), 그러나 내 더 넓은 질문은 집중 청취자를 포함하지 않는다고 생각한다. 대화 상자에서 텍스트를 편집해도 키보드가 열리지 않는 것이 일반적인 문제인 이유가 궁금합니다. kluge를 사용하는 방법이라면 기꺼이 사용할 수 있지만, 왜 그런 것이 필요한지 알고 싶습니다.
Paul

답변:


189

좋아, 그래서 많이 읽은 후 이것이 왜 문제인지 알아 냈고 어떤 해결 방법도 사용할 필요 가 없습니다 .

문제는 (적어도 내 경우에는) 텍스트를 입력하는 위치가 처음에 숨겨져 있기 때문에 AlertDialog가 자동으로 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 플래그를 설정한다는 것입니다 (또는 그와 WindowManager의 일부 조합) .LayoutParams.FLAG_NOT_FOCUSABLE)로 인해 소프트 입력이 표시되지 않습니다.

이 문제를 해결하기 위해 찾은 방법은 대화 상자가 생성 된 후 다음 줄을 추가하는 것입니다.

dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

이 작업이 완료되면 EditText는 일반적인 EditText처럼 작동하며 클러 지 또는 해결 방법이 필요하지 않습니다.


84
Create 후 플래그를 지우려고 할 때 작동하지 않았습니다. 다음과 같이 사용할 때만 작동했습니다. Dialog = builder.create (); Dialog.show (); Dialog.getWindow (). clearFlags (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); Dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
Alex Fragotsis 2013-06-06

1
@AlexanderFragotsis stackoverflow에 대한 다양한 솔루션을 시도한 후 귀하의 의견은 작동하는 유일한 솔루션입니다! 감사합니다!
Bruce

20
SOFT_INPUT_STATE_‌ VISIBLE이 작동하지 않았습니다. SOFT_INPUT_STATE_ALWAYS_VISIBLE을 사용했는데 작동했습니다. 다른 사람이 같은 문제가있는 경우 바로 거기를 알리
kb_14

예, SOFT_INPUT_STATE_VISIBLE도 작동하지 못했지만 _ALWAYS_VISIBLE 작동합니다. 아무도 거기에 무슨 일이 일어나고 있는지 알고 있습니까?
bwoogie

할 일이 매우 중요 clearFlags()후를 show(), 감사 @AlexanderFragotsis
하비에르 멘돈카

17

내 앱에서도 같은 문제가 있습니다. API 레벨> = 8 용으로 개발하는 경우 다음 스 니펫을 사용할 수 있습니다.

dialog.setOnShowListener(new OnShowListener() {
    @Override
     public void onShow(DialogInterface dialog) {
         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
         imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
    }
});

낮은 API 수준에 대한 해결책을 찾지 못했습니다 ...

BTW :이 스 니펫은 에뮬레이터에서 항상 작동하는 것은 아닙니다. 이유를 모르겠습니다.


2
이 특정 해결 방법에는 그다지 관심이 없으며 처음에는 작동하지 않는 이유에 관심이 있습니다. 추가로, 나는 실제로 키보드가 대화 상자와 함께 표시되는 것을 원하지 않으며, 일반적인 EditText의 동작과 같이 EditText가 포커스를받을 때 표시되기를 원합니다.
Paul

1
이것은 나를 위해 일했습니다. 그냥 사용 AlertDialog dialog = builder.create();전에 dialog.show();당신이 사용하는 경우 위의에 AlertDialog.Builder 후
마 코놀리

1
이것은 나를 위해 일한 유일한 사람입니다. 나는 또한 해결 방법이라고 생각하지 않습니다. 대화 상자가 실제로 표시 될 때까지 초점을 요청할 수없는 이유에 대한 Android 문서에서 아래의 답변을 인용하여 읽을 때 의미가 있습니다.
Mick Byrne 2014 년

17

AlertDialog 문서를 읽으면 다음을 찾을 수 있습니다.

에 AlertDialog의 클래스는 자동으로 설정을 담당 * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM에 대한 *를 기반 여부에서 진정한 대화 대가로 어떤 전망 View.onCheckIsTextEditor () . 일반적으로 텍스트 편집기가없는 대화 상자에 대해이 세트를 원 하므로 현재 입력 방법 UI 위에 배치됩니다. onCreate 를 호출 한 후 플래그를 원하는 모드로 강제 설정하여이 동작을 수정할 수 있습니다 .

대화 상자 내의 ListView에서 EditText에 대해 언급 한 문제가 있습니다. 하나의 메서드 만 덮어 써서 사용자 지정 뷰 클래스 (내 경우에는 ListView)를 내 FocusableListView로 덮어 써서 수정했습니다.

public class FocusableListView extends ListView {

    public FocusableListView(Context context) {
        super(context);
    }

    public FocusableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FocusableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onCheckIsTextEditor() {
        // this is where the magic happens
        return true;
    }
}

그런 다음 레이아웃 파일에서 다음과 같이 사용하고 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<com.myexample.wiget.FocusableListView 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:descendantFocusability="beforeDescendants"
android:layout_height="wrap_content" />

동일한 방식으로 귀하의 경우에 RelativeLayout을 덮어 쓸 수 있으며 작동합니다.


완벽하게 작동하지만, 안드로이드 스튜디오 (버전 1.5.1) 미리보기 레이아웃 렌더링하지 않습니다
Choletski

9

이것이 나를 위해 일한 것입니다. AlertDialog.Builder를 만들고 제목, positiveButton, negativeButton을 설정합니다. 다음을 수행하십시오.

    AlertDialog dialog = builder.create();
    dialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    dialog.show();
    editText.requestFocus();

을 사용할 필요가 없습니다 builder.show();.


감사합니다 André, 당신이 바로 그 사람입니다. 여기에 너무 많은 솔루션을 시도했습니다. 이것은 단지 하나의 노력이다
productioncoder

8

위의 코드는 매우 유용합니다. 그러나 "create"메서드 다음에 "show"메서드를 호출해야합니다 (이유는 모르겠지만 ListView의 EditText 대화 상자에서만 작동 함). onCreateDialog 메서드에서 :

@Override
protected Dialog onCreateDialog(int id) {
  switch (id) {
    case YOUR_DIALOG_ID: {
        //...
        AlertDialog a = new AlertDialog.Builder(this)./*
        ... set the properties here
        */
        .create();
        a.show(); //!!! this is very important to call the "show" method
        a.getWindow().clearFlags(
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        return a;
    }
  //...
  }
  return null;
}

그 코드가 실제로 작동합니까? a는 AlertDialog로 초기화되지만 생성자는 빌더입니다. 빌더에는 대화 상자를 반환하는 create 메서드가 있고 대화 상자에는 표시하는 show 메서드가 있습니다.
Paul

@Paul 실례합니다. 빌더가 대화를 생성하는 부분에서 코드가 실제로 잘못되었습니다. 수정했습니다.
iLya2IK

7

감사합니다! 경고 대화 상자 조각에 포함 된 ListView의 마지막 행에 포함 된 TextEdit가 있습니다. 플래그를 지우는 솔루션을 포스트 실행 파일로 사용했으며 이제 완벽하게 작동합니다.

    @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setTitle("My Title");
    m_adapter = new MyAdapter(getContext());
    builder.setAdapter(m_adapter, new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO Auto-generated method stub

        }
    }); 

    final AlertDialog dialog = builder.create();
    final ListView listView = dialog.getListView();
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

        }
    });

    listView.post(new Runnable() {

        @Override
        public void run() {
            dialog.getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);              
        }
    });
    return dialog;
}

4

한 가지 방법은 다음과 같습니다.

    final Window dialogWindow = dialog.getWindow();
    dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

2

나는 Paul의 대답Alexander의 의견 에 추가하고 싶습니다 .

나 자신이 onCreateDialog()메서드 에서 생성 된 대화 상자를 가지고 있는데 , 이는 반환이 필요한 것으로 dialog.show();보이므로 대화 상자가 생성 된 대화 상자에 layoutparams를 추가 할 수 없습니다. 이 문제를 해결하려면 onCreateDialog()방법을 동일 하게 유지 onResume()하고 다음과 같이 방법을 추가하십시오 .

@Override
public void onResume() {
    super.onResume();
    Dialog dialog = getDialog();
    dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}

이것은 트릭을 수행해야하며 고맙게도 저에게 효과적입니다. 꽤 오랫동안이 사건에 참여했습니다.


0

대화 상자에 키보드를 표시하기위한 전체 코드 :

public void onFocusChange(View v, boolean hasFocus) {
    Log.v("onFocusChange", hasFocus + " " + showkeyboard);
    if (hasFocus) {
        if (showkeyboard++ == 0) {
            alertDialog.getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
            alertDialog.getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        } else {
            showkeyboard = 1;
        }
    }
}

1
당신의 대답을 설명하려고합니다. 코드 만 넣지 마십시오. ... 각각의 코드에 구체적인 대답과 설명을 지정
Sandip ARMAL 파틸

0
This worked for me ----
editText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
//dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
InputMethodManager mgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(v, InputMethodManager.SHOW_FORCED);
editText.setFocusable(true);
}
});

0

아래 codeLine을 추가하십시오.

// editText가 대화 상자에있는 동안 자동으로 키보드를 표시합니다. dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.