Gibt es in Android eine Möglichkeit zu erkennen, ob die Software-Tastatur (auch "Soft" genannt) auf dem Bildschirm sichtbar ist?
Gibt es in Android eine Möglichkeit zu erkennen, ob die Software-Tastatur (auch "Soft" genannt) auf dem Bildschirm sichtbar ist?
Antworten:
Es gibt keinen direkten Weg - siehe http://groups.google.com/group/android-platform/browse_thread/thread/1728f26f2334c060/5e4910f0d9eb898a, wo Dianne Hackborn vom Android-Team geantwortet hat. Sie können es jedoch indirekt erkennen, indem Sie überprüfen, ob sich die Fenstergröße in #onMeasure geändert hat. Siehe So überprüfen Sie die Sichtbarkeit der Softwaretastatur in Android .
Das funktioniert bei mir. Vielleicht ist dies immer der beste Weg für alle Versionen .
Es wäre effektiv, eine Eigenschaft der Tastatursichtbarkeit festzulegen und diese Änderungen verzögert zu beobachten, da die onGlobalLayout-Methode viele Male aufgerufen wird. Es ist auch gut, die Gerätedrehung zu überprüfen und windowSoftInputMode
nicht adjustNothing
.
boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
print("keyboard " + opened);
}
// ContentView is the root view of the layout of this activity/fragment
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
onKeyboardVisibilityChanged(true)
}
}
else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
onKeyboardVisibilityChanged(false)
}
}
}
});
contentView
deklariert?
Versuche dies:
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
writeToLog("Software Keyboard was shown");
} else {
writeToLog("Software Keyboard was not shown");
}
Ich habe eine einfache Klasse erstellt, die dafür verwendet werden kann: https://github.com/ravindu1024/android-keyboardlistener . Kopieren Sie es einfach in Ihr Projekt und verwenden Sie es wie folgt:
KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener()
{
@Override
public void onToggleSoftKeyboard(boolean isVisible)
{
Log.d("keyboard", "keyboard visible: "+isVisible);
}
});
rootView
ist in diesem Fall nur eine Ansicht, die auf meine Stammansicht verweist relative layout
: a :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/addresses_confirm_root_view"
android:background="@color/WHITE_CLR">
RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);
getViewTreeObserver()
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > 100) {
Log.e("MyActivity", "keyboard opened");
} else {
Log.e("MyActivity", "keyboard closed");
}
}
});
1
. Ganz gleich. Nur dies muss kleiner sein als die tatsächliche Länge der Tastatur
Ich habe dies als Grundlage verwendet: http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
/**
* To capture the result of IMM hide/show soft keyboard
*/
public class IMMResult extends ResultReceiver {
public int result = -1;
public IMMResult() {
super(null);
}
@Override
public void onReceiveResult(int r, Bundle data) {
result = r;
}
// poll result value for up to 500 milliseconds
public int getResult() {
try {
int sleep = 0;
while (result == -1 && sleep < 500) {
Thread.sleep(100);
sleep += 100;
}
} catch (InterruptedException e) {
Log.e("IMMResult", e.getMessage());
}
return result;
}
}
Dann schrieb diese Methode:
public boolean isSoftKeyboardShown(InputMethodManager imm, View v) {
IMMResult result = new IMMResult();
int res;
imm.showSoftInput(v, 0, result);
// if keyboard doesn't change, handle the keypress
res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
return true;
}
else
return false;
}
Sie können dies dann verwenden, um alle Felder (EditText, AutoCompleteTextView usw.) zu testen, die möglicherweise ein Softkeyboard geöffnet haben:
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1))
//close the softkeyboard
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Zwar keine ideale Lösung, aber es erledigt den Job.
Sie können das Rückrufergebnis von showSoftInput () und hideSoftInput () verwenden, um den Status der Tastatur zu überprüfen. Alle Details und Beispielcode unter
http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
Sie können sich auf diese Antwort beziehen - https://stackoverflow.com/a/24105062/3629912
Es hat jedes Mal bei mir funktioniert.
adb shell dumpsys window InputMethod | grep "mHasSurface"
Es wird true zurückgegeben, wenn die Softwaretastatur sichtbar ist.
Nach einer langen Zeit des Herumspielens mit AccessibilityServices, Fenstereinfügungen, Bildschirmhöhenerkennung usw. habe ich einen Weg gefunden, dies zu tun.
Haftungsausschluss: In Android wird eine versteckte Methode verwendet, was bedeutet, dass sie möglicherweise nicht konsistent ist. Bei meinen Tests scheint es jedoch zu funktionieren.
Die Methode ist InputMethodManager # getInputMethodWindowVisibleHeight () und existiert seit Lollipop (5.0).
Ein Aufruf, der die Höhe der aktuellen Tastatur in Pixel zurückgibt. Theoretisch sollte eine Tastatur nicht 0 Pixel groß sein, daher habe ich eine einfache Höhenprüfung durchgeführt (in Kotlin):
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
if (imm.inputMethodWindowVisibleHeight > 0) {
//keyboard is shown
else {
//keyboard is hidden
}
Ich verwende die Android Hidden API , um Reflexionen zu vermeiden, wenn ich versteckte Methoden aufrufe (das mache ich häufig für die von mir entwickelten Apps, bei denen es sich hauptsächlich um Hacky / Tuner-Apps handelt), aber dies sollte auch mit Reflexionen möglich sein:
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
val windowHeightMethod = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight")
val height = windowHeightMethod.invoke(imm) as Int
//use the height val in your logic
Dies war für die Anforderungen, die ich brauchte, viel weniger kompliziert. Hoffe das könnte helfen:
Auf der Hauptaktivität:
public void dismissKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0);
mKeyboardStatus = false;
}
public void showKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
mKeyboardStatus = true;
}
private boolean isKeyboardActive(){
return mKeyboardStatus;
}
Der standardmäßige primitive boolesche Wert für mKeyboardStatus wird auf false initialisiert .
Überprüfen Sie dann den Wert wie folgt und führen Sie gegebenenfalls eine Aktion aus:
mSearchBox.requestFocus();
if(!isKeyboardActive()){
showKeyboard();
}else{
dismissKeyboard();
}
Dies sollte funktionieren, wenn Sie den Tastaturstatus überprüfen müssen:
fun Activity.isKeyboardOpened(): Boolean {
val r = Rect()
val activityRoot = getActivityRoot()
val visibleThreshold = dip(UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP)
activityRoot.getWindowVisibleDisplayFrame(r)
val heightDiff = activityRoot.rootView.height - r.height()
return heightDiff > visibleThreshold;
}
fun Activity.getActivityRoot(): View {
return (findViewById<ViewGroup>(android.R.id.content)).getChildAt(0);
}
Wobei UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP
= 100 und dip () eine Anko-Funktion ist, die dpToPx konvertiert:
fun dip(value: Int): Int {
return (value * Resources.getSystem().displayMetrics.density).toInt()
}
Dazu habe ich einen GlobalLayoutListener wie folgt festgelegt:
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightView = activityRootView.getHeight();
int widthView = activityRootView.getWidth();
if (1.0 * widthView / heightView > 3) {
//Make changes for Keyboard not visible
} else {
//Make changes for keyboard visible
}
}
});
Versuchen Sie diesen Code, es funktioniert wirklich, wenn KeyboardShown angezeigt wird, dann gibt diese Funktion den wahren Wert zurück ....
private final String TAG = "TextEditor";
private TextView mTextEditor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
mTextEditor = (TextView) findViewById(R.id.text_editor);
mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
isKeyboardShown(mTextEditor.getRootView());
}
});
}
private boolean isKeyboardShown(View rootView) {
/* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
/* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
int heightDiff = rootView.getBottom() - r.bottom;
/* Threshold size: dp to pixels, multiply with display density */
boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
+ "root view height:" + rootView.getHeight() + ", rect:" + r);
return isKeyboardShown;
}
In meinem Fall hatte ich nur eine EditText
in meinem Layout zu verwalten, also kam ich auf diese Lösung. Es funktioniert gut, im Grunde ist es eine benutzerdefinierte Funktion, EditText
die auf den Fokus wartet und eine lokale Sendung sendet, wenn sich der Fokus ändert oder wenn die Zurück / Fertig-Taste gedrückt wird. Arbeiten Sie einen Dummy platzieren müssen View
mit in Ihrem Layout android:focusable="true"
und android:focusableInTouchMode="true"
weil , wenn Sie anrufen wird clearFocus()
der Fokus auf die erste fokussierbare Ansicht neu zugewiesen werden. Beispiel für eine Dummy-Ansicht:
<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>
Zusätzliche Infos
Die Lösung, die den Unterschied bei Layoutänderungen erkennt, funktioniert nicht sehr gut, da sie stark von der Bildschirmdichte abhängt, da 100 Pixel in einem bestimmten Gerät sehr viel sein können und in einigen anderen Geräten nichts Falsches. Auch verschiedene Anbieter haben unterschiedliche Tastaturen.
In Android können Sie über ADB-Shell erkennen. Ich habe diese Methode geschrieben und angewendet:
{
JSch jsch = new JSch();
try {
Session session = jsch.getSession("<userName>", "<IP>", 22);
session.setPassword("<Password>");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
BufferedReader in = new BufferedReader(new
InputStreamReader(channel.getInputStream()));
channel.setCommand("C:/Android/android-sdk/platform-tools/adb shell dumpsys window
InputMethod | findstr \"mHasSurface\"");
channel.connect();
String msg = null;
String msg2 = " mHasSurface=true";
while ((msg = in.readLine()) != null) {
Boolean isContain = msg.contains(msg2);
log.info(isContain);
if (isContain){
log.info("Hiding keyboard...");
driver.hideKeyboard();
}
else {
log.info("No need to hide keyboard.");
}
}
channel.disconnect();
session.disconnect();
} catch (JSchException | IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
final View activityRootView = findViewById(R.id.rootlayout);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
activityRootView.getWindowVisibleDisplayFrame(r);
int screenHeight = activityRootView.getRootView().getHeight();
Log.e("screenHeight", String.valueOf(screenHeight));
int heightDiff = screenHeight - (r.bottom - r.top);
Log.e("heightDiff", String.valueOf(heightDiff));
boolean visible = heightDiff > screenHeight / 3;
Log.e("visible", String.valueOf(visible));
if (visible) {
Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show();
}
}
});
Die Antwort von @iWantScala ist großartig, aber nicht für mich zu arbeiten hat
rootView.getRootView().getHeight()
immer den gleichen Wert
Eine Möglichkeit besteht darin, zwei Vars zu definieren
private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;
globalen Listener hinzufügen
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
currentRootViewHeight = rootView.getHeight();
if (currentRootViewHeight > maxRootViewHeight) {
maxRootViewHeight = currentRootViewHeight;
}
}
});
dann überprüfe
if (currentRootViewHeight >= maxRootViewHeight) {
// Keyboard is hidden
} else {
// Keyboard is shown
}
funktioniert gut
Es gibt jetzt endlich einen direkten Weg von Android R basierend auf Kotlin.
val imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
//Ime is visible
//Lets move our view by the height of the IME
view.translationX = imeInsets.bottom }
Ich hatte ein ähnliches Problem. Ich musste auf die Eingabetaste auf dem Bildschirm reagieren (die die Tastatur verbarg). In diesem Fall können Sie die OnEditorAction der Textansicht abonnieren, mit der die Tastatur geöffnet wurde. Wenn Sie mehrere bearbeitbare Felder haben, abonnieren Sie alle.
In Ihrer Aktivität haben Sie die volle Kontrolle über die Tastatur, sodass Sie zu keinem Zeitpunkt das Problem haben, ob die Tastatur geöffnet ist oder nicht, wenn Sie alle Öffnungs- und Schließereignisse abhören.
Es gibt eine direkte Methode, um dies herauszufinden. Die Layoutänderungen sind nicht erforderlich.
So funktioniert es auch im immersiven Vollbildmodus.
Leider funktioniert es nicht auf allen Geräten. Sie müssen es also mit Ihren Geräten testen.
Der Trick besteht darin, dass Sie versuchen, die Softtastatur auszublenden oder anzuzeigen und das Ergebnis dieses Versuchs zu erfassen.
Wenn es richtig funktioniert, wird die Tastatur nicht wirklich angezeigt oder ausgeblendet. Wir fragen nur nach dem Staat.
Um auf dem neuesten Stand zu bleiben, wiederholen Sie diesen Vorgang einfach, z. B. alle 200 Millisekunden, mit einem Handler.
Die folgende Implementierung führt nur eine einzige Überprüfung durch.
Wenn Sie mehrere Überprüfungen durchführen, sollten Sie alle (_keyboardVisible) -Tests aktivieren.
public interface OnKeyboardShowHide
{
void onShowKeyboard( Object param );
void onHideKeyboard( Object param );
}
private static Handler _keyboardHandler = new Handler();
private boolean _keyboardVisible = false;
private OnKeyboardShowHide _keyboardCallback;
private Object _keyboardCallbackParam;
public void start( OnKeyboardShowHide callback, Object callbackParam )
{
_keyboardCallback = callback;
_keyboardCallbackParam = callbackParam;
//
View view = getCurrentFocus();
if (view != null)
{
InputMethodManager imm = (InputMethodManager) getSystemService( Activity.INPUT_METHOD_SERVICE );
imm.hideSoftInputFromWindow( view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY, _keyboardResultReceiver );
imm.showSoftInput( view, InputMethodManager.SHOW_IMPLICIT, _keyboardResultReceiver );
}
else // if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
}
private ResultReceiver _keyboardResultReceiver = new ResultReceiver( _keyboardHandler )
{
@Override
protected void onReceiveResult( int resultCode, Bundle resultData )
{
switch (resultCode)
{
case InputMethodManager.RESULT_SHOWN :
case InputMethodManager.RESULT_UNCHANGED_SHOWN :
// if (!_keyboardVisible)
{
_keyboardVisible = true;
_keyboardCallback.onShowKeyboard( _keyboardCallbackParam );
}
break;
case InputMethodManager.RESULT_HIDDEN :
case InputMethodManager.RESULT_UNCHANGED_HIDDEN :
// if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
break;
}
}
};
Hier ist eine Problemumgehung, um festzustellen, ob das Softkeyboard sichtbar ist.
Einige der gängigen Tastaturen haben bestimmte Schlüsselwörter in ihren Klassennamen:
Überprüfen Sie in ActivityManager.RunningServiceInfo die oben genannten Muster in ClassNames. Außerdem ist clientPackage = android von ActivityManager.RunningServiceInfo angegeben , dass die Tastatur an das System gebunden ist.
Die oben genannten Informationen können kombiniert werden, um herauszufinden, ob eine Softtastatur sichtbar ist.
Wie Sie vielleicht wissen, ist die Android-Softwaretastatur nur sichtbar, wenn ein mögliches Tippereignis vorliegt. Mit anderen Worten, die Tastatur wird nur sichtbar, wenn EditText fokussiert ist. Das bedeutet, dass Sie mithilfe von OnFocusChangeListener feststellen können , ob die Tastatur sichtbar ist oder nicht .
//Declare this Globally
public boolean isKeyBoardVisible = false;
//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*
text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
isKeyBoardVisible = true;
else
isKeyBoardVisible = false;
}
});
Jetzt können Sie die Variable isKeyBoardVisible an einer beliebigen Stelle in der Klasse verwenden, um festzustellen , ob die Tastatur geöffnet ist oder nicht. Es hat gut für mich funktioniert.
Hinweis: Dieser Vorgang funktioniert nicht, wenn die Tastatur programmgesteuert mit InputMethodManager geöffnet wird, da dadurch OnFocusChangeListener nicht aufgerufen wird.
Ich habe die Antwort in Kotlin konvertiert und hoffe, dass dies für Kotlin-Benutzer hilfreich ist.
private fun checkKeyboardVisibility() {
var isKeyboardShowing = false
binding.coordinator.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
binding.coordinator.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.coordinator.rootView.height
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
val keypadHeight = screenHeight - r.bottom
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
}
} else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
}
}
}
}
Es funktioniert mit adjustNothing-Aktivitätsflag und Lebenszyklusereignisse werden verwendet. Auch bei Kotlin:
/**
* This class uses a PopupWindow to calculate the window height when the floating keyboard is opened and closed
*
* @param activity The parent activity
* The root activity that uses this KeyboardManager
*/
class KeyboardManager(private val activity: AppCompatActivity) : PopupWindow(activity), LifecycleObserver {
private var observerList = mutableListOf<((keyboardTop: Int) -> Unit)>()
/** The last value of keyboardTop */
private var keyboardTop: Int = 0
/** The view that is used to calculate the keyboard top */
private val popupView: View?
/** The parent view */
private var parentView: View
var isKeyboardShown = false
private set
/**
* Create transparent view which will be stretched over to the full screen
*/
private fun createFullScreenView(): View {
val view = LinearLayout(activity)
view.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)
view.background = ColorDrawable(Color.TRANSPARENT)
return view
}
init {
this.popupView = createFullScreenView()
contentView = popupView
softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE or LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
inputMethodMode = INPUT_METHOD_NEEDED
parentView = activity.findViewById(android.R.id.content)
width = 0
height = LayoutParams.MATCH_PARENT
popupView.viewTreeObserver.addOnGlobalLayoutListener {
val rect = Rect()
popupView.getWindowVisibleDisplayFrame(rect)
val keyboardTop = rect.bottom
if (this.keyboardTop != keyboardTop) {
isKeyboardShown = keyboardTop < this.keyboardTop
this.keyboardTop = keyboardTop
observerList.forEach { it(keyboardTop) }
}
}
activity.lifecycle.addObserver(this)
}
/**
* This must be called after the onResume of the Activity or inside view.post { } .
* PopupWindows are not allowed to be registered before the onResume has finished
* of the Activity
*/
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun start() {
parentView.post {
if (!isShowing && parentView.windowToken != null) {
setBackgroundDrawable(ColorDrawable(0))
showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0)
}
}
}
/**
* This manager will not be used anymore
*/
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun close() {
activity.lifecycle.removeObserver(this)
observerList.clear()
dismiss()
}
/**
* Set the keyboard top observer. The observer will be notified when the keyboard top has changed.
* For example when the keyboard is opened or closed
*
* @param observer The observer to be added to this provider
*/
fun registerKeyboardTopObserver(observer: (keyboardTop: Int) -> Unit) {
observerList.add(observer)
}
}
Nützliche Methode, um die Ansicht immer über der Tastatur zu behalten
fun KeyboardManager.updateBottomMarginIfKeyboardShown(
view: View,
activity: AppCompatActivity,
// marginBottom of view when keyboard is hide
marginBottomHideKeyboard: Int,
// marginBottom of view when keybouard is shown
marginBottomShowKeyboard: Int
) {
registerKeyboardTopObserver { bottomKeyboard ->
val bottomView = ViewUtils.getFullViewBounds(view).bottom
val maxHeight = ScreenUtils.getFullScreenSize(activity.windowManager).y
// Check that view is within the window size
if (bottomView < maxHeight) {
if (bottomKeyboard < bottomView) {
ViewUtils.updateMargin(view, bottomMargin = bottomView - bottomKeyboard +
view.marginBottom + marginBottomShowKeyboard)
} else ViewUtils.updateMargin(view, bottomMargin = marginBottomHideKeyboard)
}
}
}
Wo getFullViewBounds
fun getLocationOnScreen(view: View): Point {
val location = IntArray(2)
view.getLocationOnScreen(location)
return Point(location[0], location[1])
}
fun getFullViewBounds(view: View): Rect {
val location = getLocationOnScreen(view)
return Rect(location.x, location.y, location.x + view.width,
location.y + view.height)
}
Wo getFullScreenSize
fun getFullScreenSize(wm: WindowManager? = null) =
getScreenSize(wm) { getRealSize(it) }
private fun getScreenSize(wm: WindowManager? = null, block: Display.(Point) -> Unit): Point {
val windowManager = wm ?: App.INSTANCE.getSystemService(Context.WINDOW_SERVICE)
as WindowManager
val point = Point()
windowManager.defaultDisplay.block(point)
return point
}
Wo updateMargin
fun updateMargin(
view: View,
leftMargin: Int? = null,
topMargin: Int? = null,
rightMargin: Int? = null,
bottomMargin: Int? = null
) {
val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams
if (leftMargin != null) layoutParams.leftMargin = leftMargin
if (topMargin != null) layoutParams.topMargin = topMargin
if (rightMargin != null) layoutParams.rightMargin = rightMargin
if (bottomMargin != null) layoutParams.bottomMargin = bottomMargin
view.layoutParams = layoutParams
}
Ich habe dies wie folgt gemacht, aber es ist nur relevant, wenn Ihr Ziel darin besteht, die Tastatur zu schließen / zu öffnen.
Beispiel schließen: (Überprüfen, ob die Tastatur bereits geschlossen ist, falls nicht - Schließen)
imm.showSoftInput(etSearch, InputMethodManager.HIDE_IMPLICIT_ONLY, new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode != InputMethodManager.RESULT_UNCHANGED_HIDDEN)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
a verwendet möglicherweise:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(
getClass().getSimpleName(),
String.format("conf: %s", newConfig));
if (newConfig.hardKeyboardHidden != hardKeyboardHidden) {
onHardwareKeyboardChange(newConfig.hardKeyboardHidden);
hardKeyboardHidden = newConfig.hardKeyboardHidden;
}
if (newConfig.keyboardHidden != keyboardHidden) {
onKeyboardChange(newConfig.keyboardHidden);
keyboardHidden = newConfig.hardKeyboardHidden;
}
}
public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;
//todo
private void onKeyboardChange(int keyboardHidden) {
}
//todo
private void onHardwareKeyboardChange(int hardKeyboardHidden) {
}
Ich habe Probe geschrieben .
Dieses Repository kann dabei helfen, den Tastaturstatus zu erkennen, ohne davon auszugehen, dass "Tastatur mehr als X Teil des Bildschirms sein sollte".
Wenn Sie apis für AndroidR in Ihrer App unterstützen, können Sie die folgende Methode verwenden.
In kotlin :
var imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
view.translationX = imeInsets.bottom
}
Hinweis: Dies ist nur für AndroidR verfügbar und darunter muss die Android-Version einer anderen Antwort folgen, sonst werde ich sie dafür aktualisieren.