program story

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

inputbox 2020. 10. 11. 10:32
반응형

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


그래서 일반적인 문제인 것 같습니다. 즉, 대화 상자의 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.

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

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


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

문제는 (적어도 내 경우에는) 텍스트를 입력하는 위치가 처음에 숨겨져 있기 때문에 (또는 중첩되거나) 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처럼 작동하며 클러 지 또는 해결 방법이 필요하지 않습니다.


내 앱에서도 같은 문제가 있습니다. 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 :이 스 니펫은 에뮬레이터에서 항상 작동하는 것은 아닙니다. 이유를 모르겠습니다.


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을 덮어 쓸 수 있으며 작동합니다.


위의 코드는 매우 유용합니다. 그러나 "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;
}

감사합니다! 경고 대화 상자 조각에 포함 된 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;
}

이것이 나를 위해 일한 것입니다. 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();.


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

    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);

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

I myself have a dialog that's created in the onCreateDialog() method, which (seems to) require returning dialog.show();, wherefore you can not add the layoutparams to the dialog where the dialog is created. To work around this, just keep your onCreateDialog() method the same, and add an onResume() method as follows:

@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);
}

This should do the trick, it works for me, thankfully. Have been on this case for quite some while.


full code for showing the keyboard in dialog:

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;
        }
    }
}

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);
}
});

참고URL : https://stackoverflow.com/questions/9102074/android-edittext-in-dialog-doesnt-pull-up-soft-keyboard

반응형