Androidプログラミングのソフトキーボードの隠し表示例の詳細


本論文の実例は、Androidプログラミングのソフトキーボードの隠し表示方法を分析する。皆さんに参考にしてあげます。具体的には以下の通りです。
Androidはタッチパネルに対して専門的に設計されたオペレーティングシステムで、編集ボックスをクリックすると、自動的にユーザーのためにソフトキーボードを起動し、ユーザーが入力するようにします。
では、ソフトキーボードをイジェクトすると必ず元のレイアウトの高さが減少します。システムはどうやってレイアウトの減少を処理しますか?私たちはアプリケーションでカスタマイズできますか?これらは本稿で議論するポイントである。
一、ソフトキーボード表示の原理
ソフトウェアディスクの本質は何ですか?ソフトキーボードは実はDialogです。
InputMethodServiceは私たちの入力法のためにDialogを作成し、このDialogのWindowのいくつかのパラメータ(例えばGravity)を設定して、ボトムまたはフルスクリーンで表示できるようにしました。入力ボックスをクリックすると、システムはアクティブなメインウィンドウを調整して、入力方法のために相応の空間を空けて、そのDialogをボトムに表示します。またはフルスクリーンで表示します。
二、アクティブメインウィンドウの調整
AndroidはWindows InputModeという属性を定義しています。プログラムでアクティブなメインウィンドウの調整をコントロールできるようにします。Android Manifet.xmlでActivityを設定できます。例えば:android:windowSoftInputMode=「statenchanged|adjustoPan」
この属性のオプションの値は2つの部分があり、一部はソフトキーボードの状態制御、もう一部はアクティブなメインウィンドウの調整です。前の部分は本文では議論しません。読者は自分でandroid文書を調べてください。
モード1、圧縮モード
windowSoftInputModeの値がadjusstResizeに設定されると、このActivityメインウィンドウは常にソフトキーボードの空間を残すためにサイズを調整されます。
私たちはあるコードを通してテストします。この属性を設定した後、入力方法をポップアップした時、システムは何をしましたか?
Layoutレイアウトを書き換える:

public class ResizeLayout extends LinearLayout{ 
  private static int count = 0; 
  public ResizeLayout(Context context, AttributeSet attrs) { 
   super(context, attrs); 
  } 
 @Override 
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
   super.onSizeChanged(w, h, oldw, oldh); 
   Log.e("onSizeChanged " + count++, "=>onResize called! w="+w + ",h="+h+",oldw="+oldw+",oldh="+oldh); 
  } 
  @Override 
  protected void onLayout(boolean changed, int l, int t, int r, int b) { 
   super.onLayout(changed, l, t, r, b); 
   Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t=" + t + ",r=" + r + ",b="+b); 
  } 
  @Override 
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
   super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
   Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec=" + widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec); 
}

私たちのレイアウトは以下のように設定されています。

<com.winuxxan.inputMethodTest.ResizeLayout 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/root_layout" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:orientation="vertical" 
  > 
  <EditText 
   android:layout_width="fill_parent" 
   android:layout_height="wrap_content" 
  /> 
  <LinearLayout 
    android:id="@+id/bottom_layout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" 
    android:gravity="bottom">s 
  <TextView  
   android:layout_width="fill_parent" 
   android:layout_height="wrap_content" 
   android:text="@string/hello" 
   android:background="#77777777" 
  /> 
 </LinearLayout> 
</com.winuxxan.inputMethodTest.ResizeLayout>

Android Manifest.xmlのActivity設定属性:android:window SoftInputMode=「adjusstResize」
プログラムを実行し、テキストボックスをクリックして、デバッグ情報を表示します。
E/onMeassure 6(7960)=>onMeassure caled!widthMeass reSpec=1073742144,heightMeass reSpec=1073742024
E/onMeasre 7(7960):=>onMeassure caled!widthMeass reSpec=1073742144,heightMeass reSpec=1073742025
E/onSize Chenged 8(7960):=>onSizeChenged caled!w=320,h=201,oldw=320,oldh=377
E/onLayout 9(7960):=>OnLayout caled!l=0,t=0,r=320,b=201
デバッグの結果から、テキストボックスをクリックしたときに、ルートレイアウトはオンメスア、オンザフライ、オンラヨットを呼び出していることが分かります。
実際にadjusstResizeに設定した後、ソフトキーボードがポップアップした場合、メインウィンドウのレイアウトをmeasreとlayoutしますが、layoutではウィンドウのサイズが変化していることが分かりましたので、OnizeChendを呼び出しました。
運行結果からも、本来は下のTextViewが入力法の上に突き上げられていたことが分かります。
モード2、並進モード
Windows SoftInputModeの値がadjustoPanに設定されている場合、このActivityのメインウィンドウは、ソフトキーボードの空間を残すために画面のサイズを調整しません。逆に、現在のウィンドウの内容は自動的に移動します。キーボードによって現在のフォーカスが上書きされないようにします。これは、通常は、ユーザがカバーされたコンテンツとの対話動作を得るために、ソフトキーボードをオフにすることができるので、サイズを調整することを望まない。
上記の例では、Android Manifest.xmlの属性を変更します。Android:windowSoftInputMode=「adjustoPan」
再実行し、テキストボックスをクリックして、デバッグ情報を表示します。
E/onMeasre 6(8378):=>onMeassure caled!widthMeass reSpec=1073742144,heightMeass reSpec=1073742200
E/onMeasre 7(8378):=>onMeassure caled!widthMeass reSpec=1073742144,heightMeass reSpec=1073742201
E/onLayout 8(8378):=>OnLayout caled!l=0,t=0,r=320,b=377
システムもmeasrueとlayoutを再開しましたが、layoutの過程でオンサイトChengdは起動されていないことが分かりました。これは入力法のポップアップの前後に既存のレイアウトのサイズが変更されていないことを示しています。
運行結果から見れば、下のTextViewは入力法の上に載せられていません。
実際には、入力ボックスが遮蔽されないと、モードはレイアウトを調整しないが、入力ボックスが遮蔽されると、ウィンドウはシフトされる。つまり、このモードは常に入力枠を可視として保持している。ウィンドウ全体には、タイトルバーを含めてテキストボックスが見えるように上に移動します。
モード三自動モード
プロパティwindowSoftInputModeがadjust Uspecifiedに設定されている場合、それはActivityのメインウィンドウにサイズを調整してソフトキーボードの空間を残しますか?ウィンドウの内容がスクリーン上の現在の焦点を得るかどうかが見えます。システムは、これらのモードのうちの1つを自動的に選択します。ウィンドウの内容に依存します。レイアウトビューがあれば、その内容をスクロールすることができます。このようなビューがあるならば、このウィンドウはサイズを調整します。このような仮定は、スクロールウィンドウの内容をより小さな領域で見ることができます。これはメインウィンドウのデフォルトの挙動設定です。
つまり、システムは自動的にシフトモードを採用するか、それとも圧縮モードを採用するかを決定します。
三、聴解ソフトキーボードの表示隠し
時々、システム自体のメカニズムによってメインウィンドウの調整が必要ではない結果が実現されます。ソフトキーボードが非表示になったときに、手動でレイアウトを変更して、ソフトキーボードがより美しく表示されるようにしたいです。この時はソフトキーボードの表示を隠して聞き込みを行う必要があります。
直接にソフトキーボードの表示に対して偵察の方法を隠していますが、本人が見つけられませんでした。どなたか見つけた方法があれば、ぜひ教えてください。また、この方法は圧縮モードに対して、並進モードは必ずしも有効ではない。
この特性をソフトキーボードで表示したり、隠したりすることで、メインウィンドウを再レイアウトしてリスニングすることができます。もし我々が設定したモードが圧縮モードであれば、レイアウトのオンザ・チャンゲーム関数を追跡できます。並進モードであれば、関数は呼び出されないかもしれません。
ルートレイアウトの高さは一般的には変化しないので、ルートレイアウトを書き換えることができます。
レイアウトと線形レイアウトを仮定して、モードが圧縮モードであると仮定して、入力方法がポップアップした時にあるviewを隠し、入力方法が隠している時にあるviewを表示します。

public class ResizeLayout extends LinearLayout{ 
  private OnResizeListener mListener; 
  public interface OnResizeListener { 
   void OnResize(int w, int h, int oldw, int oldh); 
  } 
  public void setOnResizeListener(OnResizeListener l) { 
   mListener = l; 
  } 
  public ResizeLayout(Context context, AttributeSet attrs) { 
   super(context, attrs); 
  } 
  @Override 
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
   super.onSizeChanged(w, h, oldw, oldh); 
   if (mListener != null) { 
    mListener.OnResize(w, h, oldw, oldh); 
   } 
  } 
}

私たちのActivityでは、以下の方法で呼び出します。

public class InputMethodTestActivity extends Activity { 
  private static final int BIGGER = 1; 
  private static final int SMALLER = 2; 
  private static final int MSG_RESIZE = 1; 
  private static final int HEIGHT_THREADHOLD = 30; 
  class InputHandler extends Handler { 
   @Override 
   public void handleMessage(Message msg) { 
    switch (msg.what) { 
    case MSG_RESIZE: { 
     if (msg.arg1 == BIGGER) { 
      findViewById(R.id.bottom_layout).setVisibility(View.VISIBLE); 
     } else { 
      findViewById(R.id.bottom_layout).setVisibility(View.GONE); 
     } 
    } 
     break; 
    default: 
     break; 
    } 
    super.handleMessage(msg); 
   } 
  } 
  private InputHandler mHandler = new InputHandler(); 
  /** Called when the activity is first created. */ 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
   super.onCreate(savedInstanceState); 
   setContentView(R.layout.main); 
   ResizeLayout layout = (ResizeLayout) findViewById(R.id.root_layout); 
   layout.setOnResizeListener(new ResizeLayout.OnResizeListener() { 
    public void OnResize(int w, int h, int oldw, int oldh) { 
     int change = BIGGER; 
     if (h < oldh) { 
      change = SMALLER; 
     } 
     Message msg = new Message(); 
     msg.what = 1; 
     msg.arg1 = change; 
     mHandler.sendMessage(msg); 
    } 
   }); 
  } 
}

ここで特に注意したいのは、OnResize Listenerで変更するViewを直接に変更することはできません。OnSizeChend関数は実際にViewで実行されているlayout方法の中で、onsize Changeでviewの表示属性を変更すると、新たにlayoutメソッドを呼び出す必要があります。しかし、私たちの方法はまたlayoutで呼び出されましたので、エラーが発生します。したがって,例ではHandlerの方法を採用した。
ここで述べたように、皆さんのAndroidプログラムの設計に役に立ちます。