Androidソフトキーボードの監視を完璧に解決

15053 ワード

最近、アプリケーションのパフォーマンスのチューニングを行っていると、入力ボックスが含まれているActivityで、ソフトキーボードがポップアップされたときに直接finishがこのActivityを落とすと、前のActivityに戻ると、インタフェースのレンダリングがソフトキーボードがタイムリーに収まらずにカートンすることがわかりました.
とても友好的ではありません.
そこで、geekの精神に基づいて、やることは極致にして、この部分を最適化してみました.
ネット上のいくつかの知識の共有を借りて、同時に自分の理解を結びつけて、最終的にプロジェクトに応用します.
コードを直接付けます.
まず、このActivityのwindowSoftInputModeプロパティをmanifestファイルで宣言します.
 1 android:windowSoftInputMode="stateVisible|adjustResize" 
Activityで必要な変数とレイアウトのイベントリスニングを宣言します.
 1 private boolean mBackEnable = false;
 2     private boolean mIsBtnBack = false;
 3     private int rootBottom = Integer.MIN_VALUE;
 4     private OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
 5         @Override
 6         public void onGlobalLayout() {
 7             Rect r = new Rect();
 8             mSearchLayout.getGlobalVisibleRect(r);
 9             //  Activity , onGlobalLayout, 
10             if (rootBottom == Integer.MIN_VALUE) {
11                 rootBottom = r.bottom;
12                 return;
13             }
14             // adjustResize, 
15             if (r.bottom < rootBottom) {
16                 mBackEnable = false;
17             } else {
18                 mBackEnable = true;
19                 if (mIsBtnBack) {
20                     finish();
21                 }
22             }
23         }
24     };

そしてonCreatメソッドでイベントリスニングを登録します
 1 mSearchLayout.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); 
注意:このmSearchlayoutはあなたのActivity全体のレイアウト参照です.
最後に、onDestroyメソッドでイベントの傍受を回収することを忘れないでください.
 1 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 2     @Override
 3     protected void onDestroy() {
 4         if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
 5             mSearchLayout.getViewTreeObserver().removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
 6         } else {
 7             mSearchLayout.getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
 8         }
 9         super.onDestroy();
10     }

ここまで、androidソフトキーボードの傍受は終わりました.
**なに?フルスクリーンって言った時、効果なかった???
よし、私も出会った...
私はプロジェクトですべてのインタフェースの浸透効果を実現しました.ActivityにadjustResizeが設定されていると思っていましたが、OnGlobalLayoutListenerはまだソフトキーボードの変化を監視することができますが、結果は何度も試してはいけません.
仕方なく、助けを求めるしかない.いくつかの資料を調べてみると、これはandroidのバグだった.次に、特定のバグ修復コードクリップを示します.
 1 public class AndroidAdjustResizeBugFix {
 2     private View mChildOfContent;
 3     private int usableHeightPrevious;
 4     private int statusBarHeight;
 5     private FrameLayout.LayoutParams frameLayoutParams;
 6     private Activity mActivity;
 7 
 8     private AndroidAdjustResizeBugFix(Activity activity) {
 9         mActivity = activity;
10         FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
11         mChildOfContent = content.getChildAt(0);
12         statusBarHeight = getStatusBarHeight();
13         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
14             public void onGlobalLayout() {
15                 possiblyResizeChildOfContent();
16             }
17         });
18         frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
19     }
20     public static void assistActivity(Activity activity) {
21         new AndroidAdjustResizeBugFix(activity);
22     }
23     private void possiblyResizeChildOfContent() {
24         int usableHeightNow = computeUsableHeight();
25         if (usableHeightNow != usableHeightPrevious) {
26             int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
27             int heightDifference = usableHeightSansKeyboard - usableHeightNow;
28             if (heightDifference > (usableHeightSansKeyboard / 4)) {
29                 // keyboard probably just became visible
30                 //  ,mChildOfContent.requestLayout() 
31                 //  1
32                 frameLayoutParams.height = usableHeightSansKeyboard - 1;
33             } else {
34                 // keyboard probably just became hidden
35                 frameLayoutParams.height = usableHeightSansKeyboard;
36             }
37             mChildOfContent.requestLayout();
38             usableHeightPrevious = usableHeightNow;
39         }
40     }
41     private int computeUsableHeight() {
42         Rect r = new Rect();
43         mChildOfContent.getWindowVisibleDisplayFrame(r);
44         return r.bottom - r.top + statusBarHeight;
45     }
46     private int getStatusBarHeight() {
47         try {
48             Class<?> c = Class.forName("com.android.internal.R$dimen");
49             Object obj = c.newInstance();
50             Field field = c.getField("status_bar_height");
51             int x = Integer.parseInt(field.get(obj).toString());
52             int dimensionPixelSize = mActivity.getResources().getDimensionPixelSize(x);
53             return dimensionPixelSize;
54         } catch (Exception e) {
55             e.printStackTrace();
56         }
57         return 0;
58     }
59 }

このクラスをツールクラスとしてプロジェクトに追加し、最適化が必要なActivityのonCreateメソッドにactivityを登録します.
1 AndroidAdjustResizeBugFix.assistActivity(this); 
以上、キーボードのイジェクトと停止をリスニングするすべての内容について説明します.