Esiste un modo in Android per rilevare se la tastiera del software (aka "soft") è visibile sullo schermo?
Esiste un modo in Android per rilevare se la tastiera del software (aka "soft") è visibile sullo schermo?
Risposte:
Non esiste un modo diretto: consultare http://groups.google.com/group/android-platform/browse_thread/thread/1728f26f2334c060/5e4910f0d9eb898a a cui ha risposto Dianne Hackborn del team Android. Tuttavia, è possibile rilevarlo indirettamente controllando se la dimensione della finestra è cambiata in #onMeasure. Vedi Come verificare la visibilità della tastiera del software in Android? .
Questo funziona per me. Forse questo è sempre il modo migliore per tutte le versioni .
Sarebbe efficace rendere una proprietà della visibilità della tastiera e osservare queste modifiche ritardate perché il metodo onGlobalLayout chiama molte volte. Inoltre è bene controllare la rotazione del dispositivo e windowSoftInputMode
non lo è 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
dichiarato?
prova questo:
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
writeToLog("Software Keyboard was shown");
} else {
writeToLog("Software Keyboard was not shown");
}
Ho creato una classe semplice che può essere utilizzata per questo: https://github.com/ravindu1024/android-keyboardlistener . Copialo nel tuo progetto e usalo come segue:
KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener()
{
@Override
public void onToggleSoftKeyboard(boolean isVisible)
{
Log.d("keyboard", "keyboard visible: "+isVisible);
}
});
rootView
è solo una vista che punta alla mia vista radice in questo caso a relative layout
:
<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
. Non importa. Solo questo deve essere inferiore alla lunghezza reale della tastiera
L'ho usato come base: 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;
}
}
Quindi ha scritto questo metodo:
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;
}
È quindi possibile utilizzarlo per testare tutti i campi (EditText, AutoCompleteTextView, ecc.) Che potrebbero aver aperto una tastiera virtuale:
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);
Inoltre non è una soluzione ideale, ma fa il lavoro.
È possibile utilizzare il risultato della richiamata di showSoftInput () e hideSoftInput () per verificare lo stato della tastiera. Dettagli completi e esempio di codice a
http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
Puoi fare riferimento a questa risposta - https://stackoverflow.com/a/24105062/3629912
Ha funzionato per me ogni volta.
adb shell dumpsys window InputMethod | grep "mHasSurface"
Restituirà vero, se la tastiera del software è visibile.
Quindi dopo molto tempo a giocare con AccessibilityServices, inserti di finestre, rilevamento dell'altezza dello schermo, ecc., Penso di aver trovato un modo per farlo.
Dichiarazione di non responsabilità: utilizza un metodo nascosto in Android, il che significa che potrebbe non essere coerente. Tuttavia, nei miei test, sembra funzionare.
Il metodo è InputMethodManager # getInputMethodWindowVisibleHeight () ed esiste da Lollipop (5.0).
Chiamata che restituisce l'altezza, in pixel, della tastiera corrente. In teoria, una tastiera non dovrebbe essere alta 0 pixel, quindi ho fatto un semplice controllo dell'altezza (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
}
Uso Android Hidden API per evitare la riflessione quando chiamo metodi nascosti (lo faccio molto per le app che sviluppo, che sono per lo più app hacky / tuner), ma questo dovrebbe essere possibile anche con reflection:
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
Questo è stato molto meno complicato per i requisiti di cui avevo bisogno. Spero che questo possa aiutare:
Sull'attività principale:
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;
}
Il valore booleano primitivo predefinito per mKeyboardStatus verrà inizializzato su false .
Quindi controllare il valore come segue ed eseguire un'azione se necessario:
mSearchBox.requestFocus();
if(!isKeyboardActive()){
showKeyboard();
}else{
dismissKeyboard();
}
Questo dovrebbe funzionare se devi controllare lo stato della tastiera:
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);
}
Dove UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP
= 100 e dip () è una funzione anko che converte dpToPx:
fun dip(value: Int): Int {
return (value * Resources.getSystem().displayMetrics.density).toInt()
}
Ho fatto questo impostando un GlobalLayoutListener, come segue:
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
}
}
});
Prova questo codice funziona davvero se viene mostrato KeyboardShown, quindi questa funzione restituisce il vero valore ....
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;
}
Nel mio caso ne avevo solo uno EditText
da gestire nel mio layout, quindi ne sono uscito con questa soluzione. Funziona bene, sostanzialmente è un'abitudine EditText
che ascolta la messa a fuoco e invia una trasmissione locale se la messa a fuoco cambia o se viene premuto il pulsante Indietro / Fine. Per funzionare è necessario posizionare un manichino View
nel layout con android:focusable="true"
e android:focusableInTouchMode="true"
perché quando si chiama clearFocus()
lo stato attivo verrà riassegnato alla prima vista attivabile. Esempio di vista fittizia:
<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>
Informazioni aggiuntive
La soluzione che rileva la differenza nelle modifiche al layout non funziona molto bene perché dipende fortemente dalla densità dello schermo, dal momento che 100px può essere molto in un determinato dispositivo e nulla in alcuni altri potresti ottenere falsi positivi. Anche diversi fornitori hanno tastiere diverse.
In Android è possibile rilevare tramite shell ADB. Ho scritto e utilizzo questo metodo:
{
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();
}
}
});
La risposta di @iWantScala è ottima ma non funziona per me
rootView.getRootView().getHeight()
ha sempre lo stesso valore
un modo è definire due diversi
private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;
aggiungi listener globale
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
currentRootViewHeight = rootView.getHeight();
if (currentRootViewHeight > maxRootViewHeight) {
maxRootViewHeight = currentRootViewHeight;
}
}
});
quindi controlla
if (currentRootViewHeight >= maxRootViewHeight) {
// Keyboard is hidden
} else {
// Keyboard is shown
}
funziona bene
C'è finalmente un modo diretto a partire da Android R basato su Kotlin ora.
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 }
Ho avuto un problema simile. Dovevo reagire al pulsante Invio sullo schermo (che nascondeva la tastiera). In questo caso puoi iscriverti alla OnEditorAction della vista di testo con cui la tastiera era aperta - se hai più caselle modificabili, quindi iscriviti a tutte.
Nella tua attività hai il pieno controllo della tastiera, quindi non dovrai mai affrontare il problema se la tastiera è aperta o meno, se ascolti tutti gli eventi di apertura e chiusura.
C'è un metodo diretto per scoprirlo. E non richiede modifiche al layout.
Quindi funziona anche in modalità fullscreen immersiva.
Ma, sfortunatamente, non funziona su tutti i dispositivi. Quindi devi provarlo con i tuoi dispositivi.
Il trucco è che si tenta di nascondere o mostrare la tastiera software e acquisire il risultato di quel tentativo.
Se funziona correttamente, la tastiera non viene mostrata o nascosta. Chiediamo solo lo stato.
Per rimanere aggiornato, è sufficiente ripetere questa operazione, ad esempio ogni 200 millisecondi, utilizzando un gestore.
L'implementazione di seguito esegue un solo controllo.
Se si eseguono più controlli, è necessario abilitare tutti i test (_keyboardVisible).
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;
}
}
};
Ecco una soluzione alternativa per sapere se il softkeyboard è visibile.
Alcune delle tastiere più diffuse hanno determinate parole chiave nei loro nomi di classe:
Da ActivityManager.RunningServiceInfo, controllare i modelli sopra in ClassNames. Inoltre, clientPackage = android di ActivityManager.RunningServiceInfo , che indica che la tastiera è collegata al sistema.
Le informazioni di cui sopra potrebbero essere combinate per un modo rigoroso di scoprire se la tastiera virtuale è visibile.
Come forse saprai, la tastiera del software Android sarà visibile solo quando c'è un possibile evento di digitazione. In altre parole, la tastiera diventa visibile solo quando EditText è attivo. ciò significa che è possibile ottenere il tempo in cui la tastiera è visibile o meno utilizzando OnFocusChangeListener .
//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;
}
});
Ora puoi usare isKeyBoardVisible variabile qualsiasi punto della classe per avere tempo con la tastiera aperta o no. Ha funzionato bene nel mio caso.
Nota: questo processo non funziona quando la tastiera viene aperta a livello di codice utilizzando InputMethodManager perché non richiama OnFocusChangeListener.
Ho convertito la risposta in kotlin, spero che questo aiuti per gli utenti di kotlin.
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
}
}
}
}
Funziona con aggiustamento Non vengono utilizzati eventi di attività e del ciclo di vita. Anche con 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)
}
}
Metodo utile per mantenere la vista sempre sopra la tastiera
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)
}
}
}
Dove 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)
}
Dove 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
}
Dove 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
}
L'ho fatto come segue, ma è pertinente solo se il tuo obiettivo è chiudere / aprire il keyboad.
Chiudi esempio: (verifica se tastiera già chiusa, in caso contrario - chiusura)
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 potrebbe usare:
@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) {
}
Ho scritto un campione .
Questo repository può aiutare a rilevare lo stato della tastiera senza supporre che "la tastiera dovrebbe essere più di X parte dello schermo"
Se supporti le API per AndroidR nella tua app, puoi utilizzare il metodo seguente.
In kotlin :
var imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
view.translationX = imeInsets.bottom
}
Nota: questo è disponibile solo per AndroidR e sotto la versione Android deve seguire alcune delle altre risposte o lo aggiornerò per quello.