Android优雅地判断软键盘弹出状态
Android優雅地判斷軟鍵盤彈出狀態
- 一、為什么要判斷軟鍵盤彈出狀態
- 二、已有的判斷方案
- 三、設計新的方案
- 四、實現效果
- 五、完整代碼
- 六、核心代碼
- 七、下載地址
一、為什么要判斷軟鍵盤彈出狀態
神馬筆記在完成筆記編輯時,會對編輯界面進行截圖以作為筆記的圖標。為了保證圖標的一致性,需要在關閉軟鍵盤后進行截圖,否則會產生2種尺寸的截圖大小。
因此,需要判斷軟鍵盤是否彈出。如果軟鍵盤彈出,則先關閉軟鍵盤,用戶才能退出編輯。
二、已有的判斷方案
http://www.cnblogs.com/shelly-li/p/5639833.html
https://blog.csdn.net/yijiaodingqiankun/article/details/81085167?utm_source=blogxgwz5
https://blog.csdn.net/sinat_31311947/article/details/53899166
https://blog.csdn.net/javazejian/article/details/52126391
所有方案一致指向,根據布局變化來判斷軟鍵盤是否彈出是最穩妥的實現方案。
三、設計新的方案
首先,需要設置Activity的windowSoftInputMode屬性為adjustResize。
當軟鍵盤狀態發生變化時,布局會相應地發生變化。再根據布局變化來判斷軟鍵盤狀態。
其次,監聽Activity的android.R.id.content控件的布局變化。
android.R.id.content是每個Activity的用戶控件的容器,存在于每一個Activity中,所以我們監聽android.R.id.content的變化可以適應所有的Activity。
再來,使用LifecycleObserver來感知Activity的狀態變化,從而決定何時啟動布局變化監聽。
最后,使用ActivityLifecycleCallbacks關心其他Activity的變化,獲取Bottom的最大值,比較當前Bottom值以及最大Bottom值,從而判斷軟鍵盤的狀態。
四、實現效果
注意左上角的變化。
軟鍵盤彈出時,顯示為“完成”按鈕。
軟鍵盤關閉時,顯示為“返回”圖標。
五、完整代碼
package club.andnext.helper;import android.app.Activity; import android.app.Application; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent;/****/ public class SoftInputHelper implements LifecycleObserver,Application.ActivityLifecycleCallbacks,ViewTreeObserver.OnGlobalLayoutListener {private static final String TAG = SoftInputHelper.class.getSimpleName();int bottom;boolean visible;Rect rect;OnSoftInputListener onSoftInputListener;FragmentActivity context;public SoftInputHelper(FragmentActivity context) {this.context = context;this.bottom = 0;this.visible = false;this.rect = new Rect();context.getLifecycle().addObserver(this);}@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)public void onCreate() {context.getApplication().registerActivityLifecycleCallbacks(this);}@OnLifecycleEvent(Lifecycle.Event.ON_START)public void onStart() {ViewTreeObserver observer = getViewTreeObserver(context);if (observer != null && observer.isAlive()) {observer.addOnGlobalLayoutListener(this);}}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)public void onStop() {ViewTreeObserver observer = getViewTreeObserver(context);if (observer != null && observer.isAlive()) {observer.removeOnGlobalLayoutListener(this);}}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)public void onDestroy() {context.getApplication().unregisterActivityLifecycleCallbacks(this);context.getLifecycle().removeObserver(this);}@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityStarted(Activity activity) {}@Overridepublic void onActivityResumed(Activity activity) {}@Overridepublic void onActivityPaused(Activity activity) {}@Overridepublic void onActivityStopped(Activity activity) {this.updateBottom(activity);}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}@Overridepublic void onActivityDestroyed(Activity activity) {}@Overridepublic void onGlobalLayout() {{this.updateBottom(context);}View target = getView(context);if (target != null) {target.getGlobalVisibleRect(rect);boolean result = rect.bottom < bottom;if (this.visible ^ result) {this.visible = result;if (onSoftInputListener != null) {onSoftInputListener.onSoftInputChanged(this, visible);}}}}public int getBottom() {return bottom;}public void setOnSoftInputListener(OnSoftInputListener listener) {this.onSoftInputListener = listener;}void updateBottom(Activity activity) {View view = getView(activity);if (view != null) {view.getGlobalVisibleRect(rect);bottom = (bottom < view.getBottom())? view.getBottom(): bottom;bottom = (bottom < rect.bottom)? rect.bottom: bottom;}Log.v(TAG, "bottom = " + bottom);}View getView(Activity activity) {View view = activity.getWindow().getDecorView().findViewById(android.R.id.content);return view;}ViewTreeObserver getViewTreeObserver(Activity activity) {View view = getView(activity);if (view == null) {return null;}return view.getViewTreeObserver();}/****/public interface OnSoftInputListener {void onSoftInputChanged(SoftInputHelper helper, boolean visible);} }六、核心代碼
需要最大Bottom值作為參考值,比較當前bottom及最大bottom,從而判斷軟鍵盤狀態。
void updateBottom(Activity activity) {View view = getView(activity);if (view != null) {view.getGlobalVisibleRect(rect);bottom = (bottom < view.getBottom())? view.getBottom(): bottom;bottom = (bottom < rect.bottom)? rect.bottom: bottom;}Log.v(TAG, "bottom = " + bottom);}將當前bottom與最大bottom比較,從而得出結論。
@Overridepublic void onGlobalLayout() {{this.updateBottom(context);}View target = getView(context);if (target != null) {target.getGlobalVisibleRect(rect);boolean result = rect.bottom < bottom;if (this.visible ^ result) {this.visible = result;if (onSoftInputListener != null) {onSoftInputListener.onSoftInputChanged(this, visible);}}}}七、下載地址
神馬筆記最新版本:【whatsnote_lastest.apk】
總結
以上是生活随笔為你收集整理的Android优雅地判断软键盘弹出状态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1660s功耗多少w_gtx660满载功
- 下一篇: Android 处理软键盘遮挡问题