Android: показывать мягкую клавиатуру автоматически, когда фокус находится на редактируемом тексте


Я показываю поле ввода с помощью AlertDialog. Элемент EditText внутри самого диалога автоматически фокусируется при вызове AlertDialog.show(), но экранная клавиатура не отображается.

как заставить программную клавиатуру автоматически отображаться при отображении диалогового окна? (и нет физической/аппаратной клавиатуры). Подобно тому, как при нажатии кнопки поиска для вызова глобального поиска автоматически отображается программная клавиатура.

24 292

24 ответа:

вы можете создать фокус слушателя на EditText на AlertDialog, потом AlertDialog ' s Window. Оттуда вы можете сделать шоу мягкой клавиатуры, позвонив setSoftInputMode.

final AlertDialog dialog = ...;

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});

для отображения использования клавиатуры:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

для скрытия клавиатуры используйте:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0); 

вы можете запросить программную клавиатуру сразу после создания диалогового окна (тест на SDK-r20)

// create dialog
final AlertDialog dialog = ...; 

// request keyboard   
dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

У меня была такая же проблема, и я решил ее с помощью следующего кода. Я не уверен, как он будет вести себя на телефоне с аппаратной клавиатурой.

// TextEdit
final EditText textEdit = new EditText(this);

// Builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Enter text");
alert.setView(textEdit);

alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        String text = textEdit.getText().toString();
        finish();
    }
});

alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        finish();
    }
});

// Dialog
AlertDialog dialog = alert.create();
dialog.setOnShowListener(new OnShowListener() {

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

dialog.show();

Я нашел этот пример http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html. Добавьте следующий код непосредственно перед alert.show().

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
<activity
    ...
    android:windowSoftInputMode="stateVisible" >
</activity>

или

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

фрагменты кода из других ответов работают, но не всегда очевидно, где их разместить в коде, особенно если вы используете AlertDialog.Builder и после официальный диалог учебник потому что он не использует final AlertDialog ... или alertDialog.show().

alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

желательно

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

потому что SOFT_INPUT_STATE_ALWAYS_VISIBLE скроет клавиатуру, если фокус переключается от EditText, где SHOW_FORCED будет держать клавиатуру отображается до тех пор, пока он явно отклоняется, даже если пользователь возвращается на рабочий стол или отображает последние приложения.

Ниже приведен рабочий код для AlertDialog, созданный с помощью пользовательского макета с EditText, определенным в XML. Он также устанавливает клавиатуру, чтобы иметь клавишу" go " и позволяет ему вызвать положительную кнопку.

alert_dialog.XML-код:

<RelativeLayout
android:id="@+id/dialogRelativeLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

    <!-- android:imeOptions="actionGo" sets the keyboard to have a "go" key instead of a "new line" key. -->
    <!-- android:inputType="textUri" disables spell check in the EditText and changes the "go" key from a check mark to an arrow. -->
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:imeOptions="actionGo"
        android:inputType="textUri"/>

</RelativeLayout>

AlertDialog.java:

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;

public class CreateDialog extends AppCompatDialogFragment {
    // The public interface is used to send information back to the activity that called CreateDialog.
    public interface CreateDialogListener {
        void onCreateDialogCancel(DialogFragment dialog);    
        void onCreateDialogOK(DialogFragment dialog);
    }

    CreateDialogListener mListener;

    // Check to make sure that the activity that called CreateDialog implements both listeners.
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (CreateDialogListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement CreateDialogListener.");
        }
    }

    // onCreateDialog requires @NonNull.
    @Override
    @NonNull
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
        LayoutInflater customDialogInflater = getActivity().getLayoutInflater();

        // Setup dialogBuilder.
        alertDialogBuilder.setTitle(R.string.title);
        alertDialogBuilder.setView(customDialogInflater.inflate(R.layout.alert_dialog, null));
        alertDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mListener.onCreateDialogCancel(CreateDialog.this);
            }
        });
        alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mListener.onCreateDialogOK(CreateDialog.this);
            }
        });

        // Assign the resulting built dialog to an AlertDialog.
        final AlertDialog alertDialog = alertDialogBuilder.create();

        // Show the keyboard when the dialog is displayed on the screen.
        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

        // We need to show alertDialog before we can setOnKeyListener below.
        alertDialog.show();

        EditText editText = (EditText) alertDialog.findViewById(R.id.editText);

        // Allow the "enter" key on the keyboard to execute "OK".
        editText.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                // If the event is a key-down event on the "enter" button, select the PositiveButton "OK".
                if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                    // Trigger the create listener.
                    mListener.onCreateDialogOK(CreateDialog.this);

                    // Manually dismiss alertDialog.
                    alertDialog.dismiss();

                    // Consume the event.
                    return true;
                } else {
                    // If any other key was pressed, do not consume the event.
                    return false;
                }
            }
        });

        // onCreateDialog requires the return of an AlertDialog.
        return alertDialog;
    }
}

посмотри этой обсуждение, которое обрабатывает ручное скрытие и отображение IME. Однако, я чувствую, что если сфокусированный EditText не поднимает IME это потому, что вы звоните AlertDialog.show() в своем OnCreate() или какой-то другой метод, который вызывается перед экраном на самом деле представлены. Перемещение его в OnPostResume() должен исправить это в этом случае я считаю.

позвольте мне указать некоторую дополнительную информацию к решению yuku, потому что мне было трудно заставить это работать! Как получить объект AlertDialog из моего AlertDialog.Строитель? Ну, это результат моего alert.show() исполнение:

final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
final EditText input = new EditText(getActivity());
alert.setView(input);

// do what you need, like setting positive and negative buttons...

final AlertDialog dialog = alert.show();

input.setOnFocusChangeListener(new OnFocusChangeListener() {
   @Override
   public void onFocusChange(View v, boolean hasFocus) {
      if(hasFocus) {
         dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
      }
   }
});

Ну, это довольно старый пост, еще есть что добавить.
эти 2 простых метода, которые помогают мне держать клавиатуру под контролем, и они работают просто отлично:

показать клавиатуру

public void showKeyboard() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View v = getCurrentFocus();
    if (v != null)
        imm.showSoftInput(v, 0);
}

спрятать клавиатуру

public void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View v = getCurrentFocus();
    if (v != null)
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

Да, вы можете сделать с setOnFocusChangeListener это поможет вам.

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});

Если кто-то становится:

не удается сделать статическую ссылку на нестатический метод getSystemService (String) из типа Activity

попробуйте добавить контекст для вызова getSystemService.

Так

InputMethodManager imm = 
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

исходный вопрос касается диалогов, и мой EditText находится в обычном представлении. Во всяком случае, я подозреваю, что это должно сработать и для большинства из вас. Итак, вот что работает для меня (выше предложенный метод с самым высоким рейтингом ничего не сделал для меня). Вот пользовательский EditView, который делает это (подклассы не нужны, но я нашел его удобным для своих целей, поскольку я хотел также захватить фокус, когда вид станет видимым).

это на самом деле в значительной степени то же самое, что и ответ лакомых кусочков. Я на самом деле не заметил его ответа вообще, так как у него было ноль голосов. Затем я собирался просто прокомментировать его сообщение, но это было бы слишком долго, поэтому я закончил делать этот пост в любом случае. тидбек указывает, что он не уверен, как это работает с устройствами, имеющими клавиатуры. Я могу подтвердить, что поведение было точно таким же в любом случае. Это так, что в портретном режиме появляется программная клавиатура, а в ландшафтном - нет. наличие физической клавиатуры выскользнуло или нет разница на моем телефоне.

потому что, я лично нашел поведение немного неудобно я выбрал для использования:InputMethodManager.SHOW_FORCED. Это работает так, как я хотел, чтобы это работало. Клавиатура становится видимой независимо от ориентации, однако, по крайней мере, на моем устройстве она не появляется, если аппаратная клавиатура была выдвинута.

import android.app.Service;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

public class BringOutTheSoftInputOnFocusEditTextView extends EditText {

    protected InputMethodManager inputMethodManager;

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

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

    public BringOutTheSoftInputOnFocusEditTextView(Context context) {
        super(context);
        init();
    }

    private void init() {
        this.inputMethodManager = (InputMethodManager)getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
        this.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    BringOutTheSoftInputOnFocusEditTextView.this.inputMethodManager.showSoftInput(BringOutTheSoftInputOnFocusEditTextView.this, InputMethodManager.SHOW_FORCED);
                }
            }
        });
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == View.VISIBLE) {
            BringOutTheSoftInputOnFocusEditTextView.this.requestFocus();
        }
    }

}

проблема, похоже, заключается в том, что поскольку место, где вы вводите текст, изначально скрыто (или вложено или что-то еще), AlertDialog автоматически устанавливает флаг WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM или WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE Так что вещи не вызывают мягкий вход, чтобы показать.

способ исправить это-добавить следующее:

(...)
// Create the dialog and show it
Dialog dialog = builder.create()
dialog.show();

// After show (this is important specially if you have a list, a pager or other view that uses a adapter), clear the flags and set the soft input mode
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

попробуйте использовать:

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

чтобы показать клавиатуру, для меня, я должен был сделать следующее

текстовое поле Android: установите фокус + мягкий ввод программно

по существу решение заключается в следующем

@Override
public void onResume() {
    super.onResume();
    //passwordInput.requestFocus(); <-- that doesn't work
    passwordInput.postDelayed(new ShowKeyboard(), 325); //250 sometimes doesn't run if returning from LockScreen
}

здесь ShowKeyboard - это

private class ShowKeyboard implements Runnable {
    @Override
    public void run() {
        passwordInput.setFocusableInTouchMode(true);
        //passwordInput.requestFocusFromTouch(); //this gives touch event to launcher in background -_-
        passwordInput.requestFocus();
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
    }
}

после успешного ввода, я также убедитесь, что я скрыть клавиатуру

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(getView().getWindowToken(), 0);

Это хороший пример для вас :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/scrollID"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <LinearLayout
            android:id="@+id/test"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:baselineAligned="true"
        android:orientation="horizontal"
        android:paddingBottom="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:weightSum="1" >

        <EditText
            android:id="@+id/txtInpuConversation"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:hint="@string/edt_Conversation" >

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/btnSend"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/btn_Conversation" />
    </LinearLayout>

</LinearLayout>

почему этот ответ-Потому что выше решение покажет вашу клавиатуру, но она не исчезнет, если вы нажмете В любом другом месте, что EditText. Так что вам нужно сделать что-то, чтобы сделать keybaord исчезнуть, когда EditText теряет фокус.

вы можете добиться этого, выполнив следующие действия:

  1. сделайте Родительский вид (вид содержимого вашей деятельности) кликабельным и фокусируемым, добавив следующие атрибуты

        android:clickable="true" 
        android:focusableInTouchMode="true" 
    
  2. выполнить метод hideKeyboard ()

        public void hideKeyboard(View view) {
            InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY );
        }
    
  3. наконец, установите onFocusChangeListener вашего edittext.

        edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideKeyboard(v);
                }
            }
        });
    

Это сложнее. Я так и сделал, и это сработало.

1.At первый вызов, чтобы скрыть мягкий ввод из окна. Это позволит скрыть мягкий ввод, если мягкая клавиатура видна или ничего не делать, если это не так.

2.Показать диалоговое окно

3.Затем просто позвоните, чтобы переключить мягкий вход.

код:

InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
//hiding soft input
inputManager.hideSoftInputFromWindow(findViewById(android.R.id.content).getWind‌​owToken(), 0);
//show dialog
yourDialog.show();
//toggle soft input
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.SHOW_IMPLICIT);

попробуй такое

некоторые из них.java

public static void showKeyboard(Activity activity, boolean show) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);

    if(show)
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
    else
        inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);
}

поместите эти методы в свой класс Util и используйте в любом месте.

Котлин

fun hideKeyboard(activity: Activity) {
    val view = activity.currentFocus
    val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    assert(view != null)
    methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}

private fun showKeyboard(activity: Activity) {
    val view = activity.currentFocus
    val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    assert(view != null)
    methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}

Java

public static void hideKeyboard(Activity activity) {
    View view = activity.getCurrentFocus();
    InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    assert methodManager != null && view != null;
    methodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

private static void showKeyboard(Activity activity) {
    View view = activity.getCurrentFocus();
    InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    assert methodManager != null && view != null;
    methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}

как horkavlna писал:

toggle

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

и скрыть клавиатура

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 

методы работы. Но показать вариантов не работают в моем случае. Так что в onCreate() Я поставил hideKeyboard(editText); затем в onStart() Я пишу toggleKeyboard(editText); и onStop() Я пишу hideKeyboard(editText);.

есть три проблемы:

1) когда приложение запускается с выключенным экраном он скроет клавиатура,

2) каждый раз, когда вы включаете экран, он будет показывать клавиатуру,

3) после завершения приложения вы можете увидеть клавиатуру на главном экране Android.

после нескольких тестов я удалил эти методы и в AndroidManifest на activity теги писал android:windowSoftInputMode="stateVisible" или android:windowSoftInputMode="stateAlwaysHidden".

Я создал хорошие функции расширения kotlin-esqe, если кто-то заинтересован

fun Activity.hideKeyBoard() {
    val view = this.currentFocus
    val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    assert(view != null)
    methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}

fun Activity.showKeyboard() {
    val view = this.currentFocus
    val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    assert(view != null)
    methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

Я называю это в onCreate (), чтобы показать клавиатуру автоматически, когда я пришел в действие.