Android 文本,软键盘使用指南
目录
- TextView的基本使用
- TextView的基本属性
- 图文混排的三种实现方式
- drawableTop,DrawableBottom,DrawableLeft,drawableRight
- 通过ImageSpan或者DynamicDrawableSpan实现
- 通过给TextView设置Html内容
- EditText的基本使用
- EditText的基本属性
- imeOption属性
- inputType属性
- 监听软键盘右下角按键
- 设置imeOption不生效的解决办法
- 修改EditText下划线的颜色
- 控制输入框最多输入20个字符(10个汉字,20个英文字符)
- 通过TextWatcher来监听输入字符串内容进行过滤
- 通过实现InputFileter来过滤,中文算两个字符,英文算一个
- 判断软键盘输入的是否有表情
- 软键盘全解
- Activity的SoftInputMethod参数讲解
- 软键盘的隐藏,显示,及判断是否显示工具类
- 软键盘弹出监听及高度获取
- 软键盘常见问题
- 非全屏模式下软键盘覆盖输入框,做背景不动,软键盘上移效果
- 全屏模式下软键盘覆盖输入框的问题,做背景不动,软键盘上移效果
- 第一种思路:获取软键盘高度后修改父布局的高度
- 思路介绍图
- 代码实现
- 第二种思路:通过添加占位图的方式将输入框上移
- 思路介绍图
- 代码
- 项目地址
- 总结
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上分支供大家学习!
总结
这篇文章是新环境下的第一篇文章,断断续续就这么过了一周了,当时是关于软键盘的问题,全屏显示情况下,软键盘的显示,背景不移动!为什么到现在才发,主要有下面两方面原因:
- 希望今后所有的关于哪一方面的问题都能在一篇文章里面找到!
- 我希望自己的每篇文章内容是有价值的,无论是对别人还是自己,能够记录下一个系列下自己踩过的所有坑!
如果你在Android开发的过程中遇到文本系列的问题在文章中找不到对应的解决办法,可以在文章底部或者我的公众号aserbao给我留言!我会和你一起探讨研究问题并持续更新文章!
百密难免一疏,文章纯手打,若有出错之处,还请各位帮忙指出!若文章内容对各位有帮助,帮忙留言点个赞,给作者一丝鼓励,谢谢!
18年的一篇老文章,希望对各位有用。
作者:aserbao
链接:https://juejin.cn/post/7120119215264104485
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
- 腾讯Bugly:对字符串匹配算法的一点理解
- 爱奇艺:安卓APP崩溃捕获方案——xCrash
- 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
- 百度APP技术:Android H5首屏优化实践
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 携程:从智行 Android 项目看组件化架构实践
- 网易新闻构建优化:如何让你的构建速度“势如闪电”?
- …
四、高级kotlin强化实战
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
从一个膜拜大神的 Demo 开始
Kotlin 写 Gradle 脚本是一种什么体验?
Kotlin 编程的三重境界
Kotlin 高阶函数
Kotlin 泛型
Kotlin 扩展
Kotlin 委托
协程“不为人知”的调试技巧
图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
六、NDK模块开发
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
八、微信小程序开发
1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓
Android 文本,软键盘使用指南相关推荐
- android自动软键盘,Android屏蔽软键盘自动弹出的解决方案
问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...
- android软键盘自动弹出,Android屏蔽软键盘自动弹出的解决方案
问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...
- Android判断软键盘弹出并隐藏的简单完美解决方案
Android判断软键盘弹出并隐藏的简单完美解决方案 参考文章: (1)Android判断软键盘弹出并隐藏的简单完美解决方案 (2)https://www.cnblogs.com/thare1307/ ...
- android setinputtype光标,Android屏蔽软键盘并且显示光标的实例详解
Android屏蔽软键盘并且显示光标的实例详解 如果是android4.0以下,那么 editText.setInputType(InputType.TYPE_NULL); 就够了,android4. ...
- Android禁用软键盘和取消禁用软键盘
最近参加了一个项目,主要需要适应带有物理键盘的小屏幕机型,因为屏幕小的原因,所以不能用软件盘,而需要使用物理键盘来进行输入操作. 找了很久,终于发现了相对适当的方法: 在BaseActivity里禁用 ...
- Android隐藏软键盘收回软键盘
代码改变世界 Android隐藏软键盘收回软键盘 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPU ...
- android 更改软键盘_如何在Android的Google键盘上更改声音和振动
android 更改软键盘 Tactile feedback from a touch screen keyboard is crucial, in my opinion, but I don't l ...
- android自定义系统键盘,Android自定义软键盘
[实例简介] Android自定义软键盘 [实例截图] [核心代码] keydemo └── keydemo ├── AndroidManifest.xml ├── bin │ ├── class ...
- android隐藏软键盘方法,Android显示和隐藏软键盘方法
InputMethodManager类 Android中软键盘的管理主要是通过InputMethodManager类来完成的. InputMethodManager对象的获取方法如下: 获取到Inpu ...
- android实现软键盘弹出,editText随键盘上移,背景不动
android实现软键盘弹出,editText随键盘上移,背景不动 前段时间有个妹子问我如题的需求,我就想,这种东西网上不是很多吗,自己试过才发现,基本都不行,各种设置配置文件的windowSoftI ...
最新文章
- python模块--如何相互调用自己写的模块
- VC++实现QQ聊天工具【源代码】
- 常见面试题:为什么HashMap不是线程安全的呢?(JDK1.7和JDK1.8角度)(看完你就能和面试官笑谈人生了)
- 刷新序号公共方法 公司内部用
- python详细安装教程3.7.0-Linux 安装Python3.7.0
- stl源码剖析_《STL源码剖析》学习笔记——空间配置器
- linux中original_如何在 Linux 中整理磁盘碎片
- Python之深入解析Python技能树的测评分析
- 在Linux下编译安装Apache2(2)
- 如何在前端生成二维码
- Ubuntu 安装 python-opencv
- SpringBoot 1.快速搭建一个 SpringBoot Maven工程
- cvpr2019论文汇总(论文/代码/项目/论文阅读)
- 房间混响时间的计算与测量
- javascript 高级程序设计(第4版)阅读笔记(一)
- stm8L 触摸库使用教程 一步一步
- 运营小技能:订阅号文章排版教程(添加图片超链接、推文采集、往期推荐)
- 多方向如何选择数据分析之营业额不一定可以决定方向
- ERA5 total precipitation的单位
- 空气质量等级c语言编程,编程小白如何快速处理空气质量数据