日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

一篇好文之Android文本软键盘全解

發布時間:2023/12/14 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一篇好文之Android文本软键盘全解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

已經有一個多月沒有寫文章了,當然,我沒失蹤,我還活著!因為換了新的工作環境,所以在接手項目的時候花了點時間……不為自己做過多借口,今后持續更新好內容(還是希望自己能周更)!
這篇文章最初是記錄一個全屏模式下輸入框被軟鍵盤覆蓋的問題,要求背景不動,輸入框上移!碰巧之后項目發版,有一點時間,就想著能不能將Android文本使用做一個總結!結合之前自己做的一些筆記,這篇文章就順利產出了!
其實換工作之后,我更希望能產出高質量的文章,所以我對于這篇文章的期待其實蠻高的,希望這篇文章能幫助所有開發者解決在Android開發過程中遇到的文本問題。當然,現在文章記錄的是自己遇到的一些問題(不是很全面),希望各位在Android開發中遇到各種關于文本類的問題可以給我留言,我們一起來討論,研究對應的解決方案,完善這篇文章及項目!

大家在學習使用Android文本軟鍵盤內容的時候遇到什么問題,歡迎在我的公眾號aserbao給我留言,無償服務!同時,歡迎大家來加入微信群二維碼討論群,一起討論Android開發技術!群二維碼定時在我公眾號更新!


文章目錄

  • 項目效果
  • TextView的基本使用
    • TextView的基本屬性
    • 圖文混排的三種實現方式
      • 1. drawableTop,DrawableBottom,DrawableLeft,drawableRight
      • 2. 通過ImageSpan或者DynamicDrawableSpan實現
      • 3. 通過給TextView設置Html內容
  • EditText的基本使用
    • 1. EditText的基本屬性
      • 1. imeOption屬性
      • 2. inputType屬性
      • 2. 監聽軟鍵盤右下角按鍵
      • 3. 設置imeOption不生效的解決辦法
    • 2. 修改EditText下劃線的顏色
    • 3. 控制輸入框最多輸入20個字符(10個漢字,20個英文字符)
      • 1. 通過TextWatcher來監聽輸入字符串內容進行過濾
      • 2. 通過實現InputFileter來過濾,中文算兩個字符,英文算一個
    • 4. 判斷軟鍵盤輸入的是否有表情
  • 軟鍵盤全解
    • Activity的SoftInputMethod參數講解
    • 軟鍵盤的隱藏,顯示,及判斷是否顯示工具類
    • 軟鍵盤彈出監聽及高度獲取
    • 軟鍵盤常見問題
      • 非全屏模式下軟鍵盤覆蓋輸入框,做背景不動,軟鍵盤上移效果
      • 全屏模式下軟鍵盤覆蓋輸入框的問題,做背景不動,軟鍵盤上移效果
        • 1. 第一種思路:獲取軟鍵盤高度后修改父布局的高度
          • 思路介紹圖
          • 代碼實現
        • 2. 第二種思路:通過添加占位圖的方式將輸入框上移
          • 思路介紹圖
          • 代碼
  • 項目地址
  • 總結

項目效果

TextView的基本使用

TextView的基本屬性

常用的屬性:

<TextViewandroid:text="@string/long_text"android:textSize="10sp"android:textColor="@color/black"android:shadowRadius="8"android:shadowColor="@color/black70"android:shadowDy="4"android:layout_width="wrap_content"android:layout_height="wrap_content" />

下面這些基本包含TextView的所有屬性,里面很多屬性大多數情況下我們都使用不到,可以稍微了解下,可以直接跳過屬性列表!

屬性作用
android:text設置顯示文本.
android:textAppearance設置文字外觀
android:textColor設置文本顏色
android:textColorHighlight被選中文字的底色,默認為藍色
android:textColorHint設置提示信息文字的顏色,默認為灰色。與hint一起使用。
android:textColorLink文字鏈接的顏色.
android:textScaleX設置文字之間間隔,默認為1.0f。
android:textSize設置文字大小,推薦度量單位”sp”,如”15sp”
android:textStyle設置字形[bold(粗體) 0, italic(斜體) 1, bolditalic(又粗又斜) 2] 可以設置一個或多個,用“|”隔開
android:typeface設置文本字體
android:height設置文本區域的高度,支持度量單位:px(像素)/dp/sp/in/mm(毫米)
android:maxHeight設置文本區域的最大高度
android:minHeight設置文本區域的最小高度
android:width設置文本區域的寬度,支持度量單位:px(像素)/dp/sp/in/mm(毫米),與layout_width 的區別看這里。
android:shadowColor指定文本陰影的顏色,需要與shadowRadius一起使用。
android:shadowDx設置陰影橫向坐標開始位置。
android:shadowDy設置陰影縱向坐標開始位置。
android:shadowRadius設置陰影的半徑。一般設置為5.0的效果比較好。
android:singleLine設置單行顯示。如果和layout_width一起使用,當文本不能全部顯示時,后面用“…”來表示。如android:text=”test_ singleLine “
android:singleLine=”true” android:layout_width=”20dp”將只顯示“t…”。如果不設置singleLine或者設置為false,文本將自動換行
android:cursorVisible設定光標為顯示/隱藏,默認顯示。
android:digits設置允許輸入哪些字符。如“1234567890.±*/% ()”
android:drawableTop\Bottom\Left\Right在text的上、下、左、右方輸出一個drawable
android:drawablePadding設置text與drawable(圖片)的間隔
android:editable設置是否可編輯。
android:editorExtras設置文本的額外的輸入數據。
android:ellipsize設置當文字過長時,該控件該如何顯示。有如下值設置:”start”—-省略號顯示在開頭;”end” ——省略號顯示在結尾;”middle”—-省略號顯示在中間;”marquee” ——以跑馬燈的方式顯示(動畫橫向移動)
android:freezesText設置保存文本的內容以及光標的位置。
android:gravity設置文本位置,設置成“center”,文本將居中顯示。
android:hintText為空時顯示的文字提示信息,可通過textColorHint設置提示信息的顏色。此屬性在 EditView中使用,但是這里也可以用。
android:imeOptions附加功能,設置右下角IME動作與編輯框相關的動作,如actionDone右下角將顯示一個“完成”,而不設置默認是一個回車符號。這個在EditView中再詳細說明,此處無用。
android:imeActionId設置IME動作ID
android:imeActionLabel設置IME動作標簽
android:includeFontPadding設置文本是否包含頂部和底部額外空白,默認為true。
android:inputMethod為文本指定輸入法,需要完全限定名(完整的包名)。例如:com.google.android.inputmethod.pinyin
android:inputType設置文本的類型,用于幫助輸入法顯示合適的鍵盤類型。在EditView中再詳細說明,這里無效果。
android:linksClickable設置鏈接是否點擊連接,即使設置了autoLink。
android:marqueeRepeatLimit在ellipsize指定marquee的情況下,設置重復滾動的次數,當設置marquee_forever時表示無限次。
android:ems設置TextView的寬度為N個字符的寬度。這里測試為一個漢字字符寬度
android:maxEms設置TextView的寬度為最長為N個字符的寬度。與ems同時使用時覆蓋ems選項。
android:minEms設置TextView的寬度為最短為N個字符的寬度。與ems同時使用時覆蓋ems選項。
android:maxLength限制顯示的文本長度,超出部分不顯示。
android:lines設置文本的行數,設置兩行就顯示兩行,即使第二行沒有數據。
android:maxLines設置文本的最大顯示行數,與width或者layout_width結合使用,超出部分自動換行,超出行數將不顯示。
android:minLines設置文本的最小行數,與lines類似。
android:lineSpacingExtra設置行間距。
android:lineSpacingMultiplier設置行間距的倍數。如”1.2”
android:numeric如果被設置,該TextView有一個數字輸入法。此處無用,設置后唯一效果是TextView有點擊效果,此屬性在EdtiView將詳細說明。
android:password以小點”*”顯示文本
android:phoneNumber設置為電話號碼的輸入方式。
android:privateImeOptions設置輸入法選項,此處無用,在EditText將進一步討論。
android:scrollHorizontally設置文本超出TextView的寬度的情況下,是否出現橫拉條。
android:selectAllOnFocus如果文本是可選擇的,讓他獲取焦點而不是將光標移動為文本的開始位置或者末尾位置。 需要再EditText中設置。
android:maxWidth設置文本區域的最大寬度
android:minWidth設置文本區域的最小寬度

圖文混排的三種實現方式

1. drawableTop,DrawableBottom,DrawableLeft,drawableRight

<TextViewandroid:id="@+id/one_pictxt_tv"android:drawableLeft="@drawable/emoji_00"android:drawableRight="@drawable/emoji_01"android:drawableBottom="@drawable/emoji_02"android:drawableTop="@drawable/emoji_03"android:text="第一種方式:\n通過drawableLeft來實現\n上下左右中間文字"style="@style/picTxt_tv_style"/>

2. 通過ImageSpan或者DynamicDrawableSpan實現

SpannableString dynamicDrawableSpan = new SpannableString("DynamicDrawableSpan");DynamicDrawableSpan drawableSpan =new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {@Overridepublic Drawable getDrawable() {Drawable d = getResources().getDrawable(R.drawable.emoji_00);d.setBounds(0, 0, 150, 150);return d;}};DynamicDrawableSpan drawableSpan2 = new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BOTTOM) {@Overridepublic Drawable getDrawable() {Drawable d = getResources().getDrawable(R.drawable.emoji_01);d.setBounds(0, 0, 150, 150);return d;}};dynamicDrawableSpan.setSpan(drawableSpan, 3, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);dynamicDrawableSpan.setSpan(drawableSpan2, 7, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);mDynamicDrawableSpanTv.setText(dynamicDrawableSpan);SpannableString imageSpan = new SpannableString("ImageSpan");Drawable d = getResources().getDrawable(R.drawable.emoji_02);d.setBounds(0, 0, 150, 150);imageSpan.setSpan(new ImageSpan(d), 3, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);mIamgeSpanTv.setText(imageSpan);

3. 通過給TextView設置Html內容

如果要包含圖片的話需要重寫一個類實現ImageGetter接口并重寫getDrawable方法,具體實現可以下載底部項目源碼!

mThreePictxtTv.setText(Html.fromHtml("點擊我,帶你到HtmlTextActivity中去<font color= '#ff0000'>textView通過Html實現圖文混排</font> 點擊這一段"));

帶圖片的html的設置:

String g = "<html>" +"<head>" + "</head>" +"<body style=\"text-align: justify\">" + "\t<h3>Android性能優化之APK瘦身詳解(瘦身73%)</h3>" +"\t<P>公司項目在不斷的改版迭代中,代碼在不斷的累加,終于apk包不負重負了,已經到了八十多M了。可能要換種方式表達,到目前為止沒有正真的往外推過,一直在內部執行7天討論需求,5天代碼實現的階段。你在寫上個版本的內容,好了,下個版本的更新內容已經定稿了。基于這種快速開發的現狀,我們app優化前已經有87.1M了,包大了,運營說這樣轉化不高,只能好好搞一下咯。優化過后包大小為23.1M(優化了73%,不要說我標題黨)。好了好了,我要闡述我的apk超級無敵魔鬼瘦身之心得了。</p>" +"" +"\t<img src=\"imgs/0.png\" style=\"width: 100%;\" />" + "" + "</body>" +"</html>";mHtmlTv.setText(Html.fromHtml(htmlContent, new MImageGetter(mHtmlTv,HtmlTextActivity.this),null));public class MImageGetter implements ImageGetter {Context c;public MImageGetter(TextView text, Context c) {this.c = c;}public Drawable getDrawable(String source) {Drawable drawable = null;InputStream is = null;try {is = c.getResources().getAssets().open(source);} catch (IOException e1) {e1.printStackTrace();}try {TypedValue typedValue = new TypedValue();typedValue.density = TypedValue.DENSITY_DEFAULT;drawable = Drawable.createFromResourceStream(null, typedValue, is, "src");DisplayMetrics dm = c.getResources().getDisplayMetrics();int dwidth = dm.widthPixels-10;//padding left + padding right float dheight = (float)drawable.getIntrinsicHeight()*(float)dwidth/(float)drawable.getIntrinsicWidth();int dh = (int)(dheight+0.5);int wid = dwidth;int hei = dh;drawable.setBounds(0, 0, wid, hei);return drawable;} catch (Exception e) {System.out.println(e);return null;} } }

EditText的基本使用

1. EditText的基本屬性

<EditTextandroid:textIsSelectable="true" //文本是否可選,復制粘貼剪輯,在TextVew中使用,在EditText中使用此屬性將收不到軟鍵盤輸入內容android:id="@+id/pop_select_label_et"android:layout_weight="1"android:paddingLeft="25dp"android:background="@drawable/find_num_tv_bg"//@null 取消下劃線android:hint="輸入話題"android:maxLength="30"android:textColorHint="@color/white"android:textColor="@color/white"android:singleLine="true"android:imeOptions="actionSearch"//軟鍵盤右下方修改為搜索android:layout_width="0dp"android:textCursorDrawable="@drawable/text_view_cursor" //修改光標的顏色android:textSize="15sp"android:cursorVisible="false"//是否顯示光標android:focusable="true"//是否可以focuandroid:layout_height="match_parent"/>

1. imeOption屬性

imeOptions:值:

  • actionDone:完成,對應常量EditorInfo.IME_ACTION_DONE
  • actionSend :發送,對應常量EditorInfo.IME_ACTION_SEND
  • actionSearch 搜索,對應常量EditorInfo.IME_ACTION_SEARCH
  • actionGo 去往,對應常量EditorInfo.IME_ACTION_GO
  • actionNone 沒有動作,對應常量EditorInfo.IME_ACTION_NONE
  • actionUnspecified 未指定,默認,對應常量EditorInfo.IME_ACTION_UNSPECIFIED.
  • actionNext 下一個,對應常量EditorInfo.IME_ACTION_NEXT

2. inputType屬性

android:inputType="phone" //電話號碼android:inputType="none" //文本類型,多為大寫、小寫和數字符號。 android:inputType="text" android:inputType="textCapCharacters" //字母大寫 android:inputType="textCapWords" //首字母大寫 android:inputType="textCapSentences" //僅第一個字母大寫 android:inputType="textAutoCorrect" //自動完成 android:inputType="textAutoComplete" //自動完成 android:inputType="textMultiLine" //多行輸入 android:inputType="textImeMultiLine" //輸入法多行(如果支持) android:inputType="textNoSuggestions" //不提示 android:inputType="textUri" //網址 android:inputType="textEmailAddress" //電子郵件地址 android:inputType="textEmailSubject" //郵件主題 android:inputType="textShortMessage" //短訊 android:inputType="textLongMessage" //長信息 android:inputType="textPersonName" //人名 android:inputType="textPostalAddress" //地址android:inputType="textPassword" //密碼 android:inputType="textVisiblePassword" //可見密碼android:inputType="textWebEditText" //作為網頁表單的文本 android:inputType="textFilter" //文本篩選過濾 android:inputType="textPhonetic" //拼音輸入 //數值類型 android:inputType="number" //數字 android:inputType="numberSigned" //帶符號數字格式 android:inputType="numberDecimal" //帶小數點的浮點格式 android:inputType="datetime" //時間日期 android:inputType="date" //日期鍵盤 android:inputType="time" //時間鍵盤

2. 監聽軟鍵盤右下角按鍵

editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {@Overridepublic boolean onEditorAction(TextView v, int actionId, KeyEvent event) {switch (actionId){case EditorInfo.IME_ACTION_SEARCH:break;case EditorInfo.IME_ACTION_DONE:break;case EditorInfo.IME_ACTION_SEND:break;case EditorInfo.IME_ACTION_GO:break;case EditorInfo.IME_ACTION_NONE:break;case EditorInfo.IME_ACTION_NEXT:break;case EditorInfo.IME_ACTION_UNSPECIFIED:break;}return false;}});

3. 設置imeOption不生效的解決辦法

設置imeOption無效:需要將singleLine設置為true或者 將inputType設置為text

2. 修改EditText下劃線的顏色

//1. 通過修改colorAccent屬性來修改下劃線顏色,此方法會全局修改<item name="colorAccent">@color/colorWhite80</item>//2. 通過修改EditText的style來修改下劃線顏色 <style name="MyEditText2" parent="Theme.AppCompat.Light"><item name="colorControlNormal">@color/colorWhite80</item> //控件默認的顏色<item name="colorControlActivated">@color/colorWhite50</item> // 控件被激活的顏色 </style>

3. 控制輸入框最多輸入20個字符(10個漢字,20個英文字符)

Android原生計算方法沒有漢字和英文字符的區分,所以當產品有這個需求的時候,只能通過過濾計算去限制輸入!這里提供兩種方案:

1. 通過TextWatcher來監聽輸入字符串內容進行過濾

editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {int charSequenceCount = countChineseChar(s);if (s.length() + charSequenceCount > StaticFinalValues.MAX_CHAR_NUM_SELECT) {CharSequence text = s.subSequence(0, s.length() - 1);editText.setText(text);editText.setSelection(text.length());//光標跳最后if(System.currentTimeMillis() - mLastTime > 500) {Toast.makeText(mContext, "輸入不能多于" + String.valueOf( StaticFinalValues.MAX_CHAR_NUM_SELECT) +"字符", Toast.LENGTH_SHORT).show();mLastTime = System.currentTimeMillis();}return;}}});/*** 計算中文字符** @param sequence* @return*/public static int countChineseChar(CharSequence sequence) {if (TextUtils.isEmpty(sequence)) {return 0;}int charNum = 0;for (int i = 0; i < sequence.length(); i++) {char word = sequence.charAt(i);if (UiUtils.isChineseChar(word)) {//中文charNum++;}}return charNum;}/*** 判斷是否是中文* @param c* @return*/public static boolean isChineseChar(char c) {Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {return true;}return false;}

2. 通過實現InputFileter來過濾,中文算兩個字符,英文算一個

public class MaxLengthEditText extends AppCompatEditText {public MaxLengthEditText(Context context, AttributeSet attrs) {super(context, attrs);initLength(attrs,context);}public MaxLengthEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initLength(attrs,context);}private void initLength(AttributeSet a, Context context) {//命名空間(別告訴我不熟悉)String namespace = "http://schemas.android.com/apk/res/android";//獲取屬性中設置的最大長度int maxLength = a.getAttributeIntValue(namespace, "maxLength", -1);//如果設置了最大長度,給出相應的處理if (maxLength > -1) {setFilters(new InputFilter[]{new MaxLengthEditText.MyLengthFilter(maxLength,context)});}}/*** 從源碼中復制出來的* 來源:InputFilter.LengthFilter* 這里只是添加了一句話:* Toast.makeText(context, "字數不能超過" + mMax, Toast.LENGTH_SHORT).show();** This filter will constrain edits not to make the length of the text* greater than the specified length.*/class MyLengthFilter implements InputFilter {private final int mMax;private Context context;public MyLengthFilter(int max, Context context) {mMax = max;this.context = context;}public CharSequence filter(CharSequence source, int start, int end, Spanned dest,int dstart, int dend) {int keep = 0;for (int i = 0; i < dest.length(); i++) {char charAt = dest.charAt(i);//32-122包含了空格,大小寫字母,數字和一些常用的符號,//如果在這個范圍內則算一個字符,//如果不在這個范圍比如是漢字的話就是兩個字符if (charAt >= 32 && charAt <= 122) {keep++;} else {keep += 2;}}if(keep <= mMax){return source.subSequence(start, source.length());}else{Toast.makeText(mContext, "輸入少一點,太多了", Toast.LENGTH_SHORT).show();return "";}}/*** @return the maximum length enforced by this input filter*/public int getMax() {return mMax;}} }

4. 判斷軟鍵盤輸入的是否有表情

若需求聲明,表情只能算一個字符,這時候就需要在輸入后進行判斷:

@Overridepublic void afterTextChanged(Editable s) {String s1 = s.toString();char[] sC = new char[s1.length()];s1.getChars(0,s1.length(),sC,0);for (char c : sC) {Log.e(TAG, "afterTextChanged: "+ isEmojiCharacter(c));}}private static boolean isEmojiCharacter(char codePoint) {return !((codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && codePoint <= 0xD7FF))|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));}

軟鍵盤全解

Activity的SoftInputMethod參數講解

屬性作用
stateUnspecified未指定狀態,系統默認采用的交互方式,默認不彈出軟鍵盤,但是對于輸入框界面有滾動布局時且EditText獲得焦點時,軟鍵盤彈出
stateUnchanged狀態不改變 ,當前界面的軟鍵盤是否顯示,取決于上一個Activity軟鍵盤的狀態
stateHidden軟鍵盤一定是隱藏
stateAlwaysHidden軟鍵盤一定是隱藏,暫時沒發現和stateHidden有啥區別
stateVisible設置為這個屬性,可以將軟鍵盤召喚出來,即使在界面上沒有輸入框的情況下也可以強制召喚出來
stateAlwaysVisible軟鍵盤默認顯示,當給AActivity設置stateVisible屬性時,從當前AActivity跳轉到BActivity,軟鍵盤隱藏,再從BActivity返回AActivity,軟鍵盤不顯示!當設置stateAlwaysVisible屬性時,跳轉后的返回軟鍵盤依舊顯示!
adjustUnspecified系統默認屬性,默認adjustPan的效果!如果在設置這個屬性之前設置過adjustResize,則會是adjustResize的效果!如果上一次設置為adjustPan,再設置為adjustUnspecified,則會是adjustPan的效果!
adjustResize設置這個屬性,當前Activity總會給軟鍵盤預留顯示空間,輸入框被彈出軟鍵盤覆蓋掉,有兩種情況:1. 有滾動布局,其他布局不移動且大小不改變,輸入框移動到軟鍵盤上面 2. 無滾動布局,通過修改其他布局的大小達到輸入框移動到軟鍵盤的效果
adjustPan設置這個屬性,Activity不會預留軟鍵盤顯示空間,而是通過布局移動來保證輸入框不被軟鍵盤覆蓋!只要輸入框被軟鍵盤覆蓋,就會通過移動整個布局來達到顯示輸入框的效果!
注意當Activity設置全屏后,adjustResize和adjustPan沒有任何區別!無論是否有滾動布局,Activity都會往上移動

軟鍵盤的隱藏,顯示,及判斷是否顯示工具類

public class AppKeyBoardMgr {/*** 打開軟鍵盤* @param mEditText 輸入框* @param mContext 上下文*/public static void openKeybord(EditText mEditText, Context mContext){InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);}/*** 顯示輸入法* @param mAct activity*/public static void showInputMethod(final Activity mAct) {View v = mAct.getCurrentFocus();if (null == v) {return;}((InputMethodManager) mAct.getSystemService(Activity.INPUT_METHOD_SERVICE)).showSoftInput(v, 0);}/*** 強制顯示輸入法鍵盤*/public static void showKeybord(EditText edittext) {InputMethodManager inputMethodManager = (InputMethodManager)edittext.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_FORCED);}/*** 關閉軟鍵盤* @param mEditText 輸入框* @param mContext 上下文*/public static void closeKeybord(EditText mEditText, Context mContext){InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);}/*** 強制隱藏輸入法鍵盤*/public static void hideKeybord(EditText edittext) {InputMethodManager inputMethodManager = (InputMethodManager)edittext.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);if (inputMethodManager.isActive()) {inputMethodManager.hideSoftInputFromWindow(edittext.getWindowToken(), 0);}}/*** 隱藏輸入法* @param mAct activity*/public static void hideInputMethod(Activity mAct) {try {// hide keybord anywayView v = mAct.getWindow().getCurrentFocus();if (v != null) {InputMethodManager imm = (InputMethodManager) mAct.getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(v.getWindowToken(), 0);}} catch (Exception e) {}}/*** 通過定時器強制隱藏虛擬鍵盤*/public static void TimerHideKeyboard(final View v) {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);if (imm.isActive()) {imm.hideSoftInputFromWindow(v.getApplicationWindowToken(),0);}}}, 10);}/*** 切換軟鍵盤的狀態* 如當前為收起變為彈出,若當前為彈出變為收起*/public static void toggleKeybord(EditText edittext) {InputMethodManager inputMethodManager = (InputMethodManager)edittext.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);}/*** 輸入法是否顯示*/public static boolean isKeybord(EditText edittext) {boolean bool = false;InputMethodManager inputMethodManager = (InputMethodManager)edittext.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);if (inputMethodManager.isActive()) {bool = true;}return bool;} }

軟鍵盤彈出監聽及高度獲取

Android系統沒有對軟鍵盤做特別的開放監聽接口,一般情況下我們可以通過布局的addOnGlobalLayoutListener接口來獲取軟鍵盤是否顯示的監聽!
提別提醒:如果設置了屬性adjustNothing,布局沒有任何改變,addOnGlobalLayoutListener這個監聽是不會有回調的!

特別說明:下面計算軟鍵盤高度通過兩種方式來獲取,為了兼容,這里采用兩種方式取最小值來獲取軟鍵盤高度,一種是通過反射系統方法getInputMethodWindowVisibleHeight()方法來獲取軟鍵盤高度,一種通過計算布局顯示高度來確認軟鍵盤高度!

//拿到當前XML文件的根布局mChildContent = (FrameLayout) findViewById(android.R.id.content);//監聽當前View的狀態,進行通知回調,即"軟鍵盤彈出""View childew = mChildContent.getChildAt(0);childew.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {public void onGlobalLayout() {//反射獲取InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);int injectSoftHeight = 0;try {Method method = inputMethodManager.getClass().getDeclaredMethod("getInputMethodWindowVisibleHeight", null);method.setAccessible(true);injectSoftHeight = (Integer) method.invoke(inputMethodManager, null);} catch (Exception e) {e.printStackTrace();}//布局顯示高度差來計算View decorView = getWindow().getDecorView();Rect r = new Rect();//r will be populated with the coordinates of your view that area still visible.decorView.getWindowVisibleDisplayFrame(r);int rootHeight = decorView.getRootView().getHeight();int rH = r.bottom - r.top;int measureDVHeight = rootHeight - rH;if (injectSoftHeight > 200) {mMeasureSoftKBHeight = injectSoftHeight < measureDVHeight ? injectSoftHeight : measureDVHeight;} else if (injectSoftHeight <= 200) {mMeasureSoftKBHeight = measureDVHeight;}if (mLastHeight != mMeasureSoftKBHeight) {if (mMeasureSoftKBHeight > 200) {//200這個值視情況而定,目前設置這個值沒有出現兼容問題//軟鍵盤顯示} else {//軟鍵盤隱藏}mLastHeight = mMeasureSoftKBHeight;}}});

軟鍵盤常見問題

非全屏模式下軟鍵盤覆蓋輸入框,做背景不動,軟鍵盤上移效果

這種情況,直接通過設置帶滾動布局,設置adjustResize屬性就可以實現效果

全屏模式下軟鍵盤覆蓋輸入框的問題,做背景不動,軟鍵盤上移效果

1. 第一種思路:獲取軟鍵盤高度后修改父布局的高度

思路介紹圖

思路參考于:AndroidBug5497Workaround

代碼實現
//思路參考于:AndroidBug5497Workaround public class AndroidSoftBoardAdjustHeightUtil {public static void assistActivity(Activity activity) {new AndroidSoftBoardAdjustHeightUtil(activity); } private View mChildOfContent;private int usableHeightPrevious; private FrameLayout.LayoutParams frameLayoutParams;private AndroidSoftBoardAdjustHeightUtil(Activity activity) {FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);mChildOfContent = content.getChildAt(0); mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {public void onGlobalLayout() { possiblyResizeChildOfContent(); } }); frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); } private void possiblyResizeChildOfContent() { int usableHeightNow = computeUsableHeight(); if (usableHeightNow != usableHeightPrevious) { int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight(); int heightDifference = usableHeightSansKeyboard - usableHeightNow; //排除其他View引起的變化,專注軟鍵盤變化 if (heightDifference > (usableHeightSansKeyboard / 4)) { // keyboard probably just became visible frameLayoutParams.height = usableHeightSansKeyboard - heightDifference; //減掉軟鍵盤的高度} else { // keyboard probably just became hidden frameLayoutParams.height = usableHeightSansKeyboard; } mChildOfContent.requestLayout(); usableHeightPrevious = usableHeightNow; } } private int computeUsableHeight() { Rect r = new Rect();//這行代碼能夠獲取到去除標題欄和被軟鍵盤擋住的部分,所剩下的矩形區域 mChildOfContent.getWindowVisibleDisplayFrame(r); //r.top : 標題欄的高度 //屏幕高度-r.bottom : 軟鍵盤的高度 //可用高度(全屏模式) : rect.bottom //可用高度(非全屏模式) : rect.bottom - rect.top return (r.bottom - r.top);// 全屏模式下: return r.bottom } }

2. 第二種思路:通過添加占位圖的方式將輸入框上移

思路介紹圖

由于第一種方式會有兼容問題,而且軟鍵盤彈出的時候部分手機會出現閃爍現象!

  • 通過設置下圖中的PlaceholderView的Visible和Gone來控制EditText的高度
  • 代碼
  • 在輸入框onTouch事件的時候將占位視圖顯示出來,防止閃爍問題
  • 在監聽到軟鍵盤彈出之后,通過視圖的偏移高度和反射調用getInputMethodWindowVisibleHeight獲取軟鍵盤高度取最小值!(為了適配手機虛擬鍵盤高度計算,本人自測,任何一種方式都不能兼容到所有手機,最終通過取兩種計算結果下的最小值來解決這個問題!)
  • private void initCheckKeyBoardIsShow(final EditText editText) {editText.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {editText.setCursorVisible(true);mPlaceholderTv.setVisibility(View.VISIBLE);return false;}});//拿到當前XML文件的根布局mChildContent = (FrameLayout) findViewById(android.R.id.content);//監聽當前View的狀態,進行通知回調,即"軟鍵盤彈出""View childew = mChildContent.getChildAt(0);childew.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {public void onGlobalLayout() {InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);int injectSoftHeight = 0;try {Method method = inputMethodManager.getClass().getDeclaredMethod("getInputMethodWindowVisibleHeight", null);method.setAccessible(true);injectSoftHeight = (Integer) method.invoke(inputMethodManager, null);} catch (Exception e) {e.printStackTrace();}View decorView = getWindow().getDecorView();Rect r = new Rect();decorView.getWindowVisibleDisplayFrame(r);int rootHeight = decorView.getRootView().getHeight();int rH = r.bottom - r.top;int measureDVHeight = rootHeight - rH;if (injectSoftHeight > 200) {mMeasureSoftKBHeight = injectSoftHeight < measureDVHeight ? injectSoftHeight : measureDVHeight;} else if (injectSoftHeight <= 200) {mMeasureSoftKBHeight = measureDVHeight;}if (mLastHeight != mMeasureSoftKBHeight) {if (mMeasureSoftKBHeight > 200) {LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mPlaceholderTv.getLayoutParams();int result = 0;result = mMeasureSoftKBHeight;layoutParams.height = result;mPlaceholderTv.setLayoutParams(layoutParams);mPlaceholderTv.postInvalidate();setRecordBtnMargain(mMeasureSoftKBHeight);} else {setRecordBtnMargain(0);mNewStoryEt.setCursorVisible(false);mPlaceholderTv.setVisibility(View.GONE);}mLastHeight = mMeasureSoftKBHeight;}}});}

    項目地址

    AserbaosAndroid
    aserbao的個人Android總結項目,希望這個項目能成為最全面的Android開發學習項目,這是個美好的愿景,項目中還有很多未涉及到的地方,有很多沒有講到的點,希望看到這個項目的朋友,如果你在開發中遇到什么問題,在這個項目中沒有找到對應的解決辦法,希望你能夠提出來,給我留言或者在項目github地址提issues,我有時間就會更新項目沒有涉及到的部分!項目會一直維護下去。當然,我希望是Aserbao’sAndroid 能為所有Android開發者提供到幫助!也期望更多Android開發者能參與進來,只要你熟悉Android某一塊,都可以將你的代碼pull上分支供大家學習!

    總結

    這篇文章是新環境下的第一篇文章,斷斷續續就這么過了一周了,當時是關于軟鍵盤的問題,全屏顯示情況下,軟鍵盤的顯示,背景不移動!為什么到現在才發,主要有下面兩方面原因:

  • 希望今后所有的關于哪一方面的問題都能在一篇文章里面找到!
  • 我希望自己的每篇文章內容是有價值的,無論是對別人還是自己,能夠記錄下一個系列下自己踩過的所有坑!
  • 這篇文章最后定義為《初級》,意為所有常見開發中會遇到的文本問題都會在這篇文章中同步更新,后面會有兩篇《中級》《高級》,中級會講自定義軟鍵盤的內容,高級會分析Andriod軟件軟鍵盤的整體實現架構!目前的思路是這樣的!

    如果你在Android開發的過程中遇到文本系列的問題在文章中找不到對應的解決辦法,可以在文章底部或者我的公眾號aserbao給我留言!我會和你一起探討研究問題并持續更新文章!

    百密難免一疏,文章純手打,若有出錯之處,還請各位幫忙指出!若文章內容對各位有幫助,幫忙留言點個贊,給作者一絲鼓勵,謝謝!

    總結

    以上是生活随笔為你收集整理的一篇好文之Android文本软键盘全解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美日韩精品一区二区在线播放 | 福利视频导航网 | 国产精品综合一区二区 | 日韩一中文字幕 | 中文字幕福利 | 日韩在线观看一区 | 99在线看 | 男人操女人的软件 | 男女激情网址 | 韩日av一区二区 | 日韩不卡一二三区 | 中文字幕一区二区三区久久久 | 双性娇喘浑圆奶水h男男漫画 | 亚洲天堂伦理 | 婷婷久 | 午夜888 | 中文字幕一区二区不卡 | av中字 | 精产国品一区二区 | 在线播放日韩av | 日韩在线电影一区 | 国产21页| 国产a视频免费观看 | 精品欧美日韩 | 麻豆av导航 | 欧美综合一区二区三区 | 国语对白永久免费 | 少妇野外性xx老女人野外性xx | 亚洲欧美日韩一区二区 | 日韩中文在线字幕 | 黄色一级大片在线免费看产 | 男人的天堂久久久 | www.x日本| 亚洲成人少妇 | 亚洲欧美国产视频 | 美国免费高清电影在线观看 | 五月天婷婷激情网 | 国产精品yy | 狠狠操在线播放 | 6080av| 免费av免费观看 | 九九九九九热 | 国产一级片a | 中文字幕日韩精品亚洲一区小树林 | 久久精品—区二区三区舞蹈 | 噼里啪啦高清 | 中文无码日韩欧 | 体内精69xxxxxx | 长篇h版少妇沉沦交换 | 九九视频免费 | 亚洲小视频 | 亚洲自拍偷拍一区二区三区 | 亚洲黄色片在线观看 | 森泽佳奈av | 国产精品成久久久久三级 | 性猛交xxxx乱大交孕妇印度 | 国产第一页精品 | 视频一区二区三区四区五区 | 黄色成人在线视频 | 打美女屁股网站 | 黄色1级视频 | 牛牛免费视频 | 免费视频网站在线观看入口 | 色哟哟网站在线观看 | 黄色网页在线看 | 久久爱伊人 | 国产一级二级三级在线 | 国产欧美在线播放 | 一级黄色录像大片 | 亚洲一片 | sese久久 | 日韩精品免费观看 | 三级全黄视频 | 亚洲色图15p | 蜜桃久久久 | 久久久久久久亚洲精品 | www.色偷偷| 2018av| 免费观看一区 | 欧美性插动态图 | 麻豆国产尤物av尤物在线观看 | 欧美专区在线播放 | 久久99国产精品一区 | 欧美一区二区久久久 | 免费久久精品视频 | 快色污 | 你懂的网址在线观看 | 少妇性l交大片免费观看 | 亚洲永久精品一区二区 | 激情亚洲天堂 | 一级黄网| 久久久精品日韩 | 成人一区二区三区在线观看 | 亚洲三级免费 | 日韩免费福利视频 | 最好看的中文字幕 | 日本一区视频在线 | 久久精品国产露脸对白 | 青青福利视频 |