android输入法窗口大小,Android_光标&&window如何因为输入法而重新计算大小

本文详细探讨了Android中EditText禁止软键盘弹出的API使用,光标的绘制与闪烁机制,以及输入法弹出时Activity窗口大小的调整。针对不同Android版本,提供了禁止软键盘显示的解决方案,并解析了光标绘制的源码流程。同时,介绍了Activity在输入法弹出时如何调整窗口大小的原理,涉及WindowManager和InputMethodManager的相关知识。
摘要由CSDN通过智能技术生成

本文讨论以下几个方面的问题以及解决办法

1,Edittext,获取焦点但是禁止软键盘的弹出,

2,光标的产生原理

3,activity是如何在输入法弹出后调整窗口大小的

1.Edittext,获取焦点但是禁止软键盘的弹出

Android api21 放开了TextView的setShowSoftInputOnFocus方法可以设置在获取焦点的时候不显示软键盘,但是在Android api21以下该方法是隐藏的

api 21以上

/**

* Sets whether the soft input method will be made visible when this

* TextView gets focused. The default is true.

*/

@android.view.RemotableViewMethod

public final void setShowSoftInputOnFocus(boolean show) {

createEditorIfNeeded();

mEditor.mShowSoftInputOnFocus = show;

}

api21以下

/**

* Sets whether the soft input method will be made visible when this

* TextView gets focused. The default is true.

* @hide

*/

@android.view.RemotableViewMethod

public final void setShowSoftInputOnFocus(boolean show) {

createEditorIfNeeded();

mEditor.mShowSoftInputOnFocus = show;

}

因此解决办法是当api小于21的时候使用反射调用setShowSoftInputOnFocus方法

如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

editText.setShowSoftInputOnFocus(false);

}else {

//这里采用反射调用被隐藏方法

setShowSoftInputOnFocus(editText,false);

}

private void setShowSoftInputOnFocus(EditText editText,boolean show) {

try {

Class cls = EditText.class;

Method setShowSoftInputOnFocus;

setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus",

boolean.class);

setShowSoftInputOnFocus.setAccessible(true);

setShowSoftInputOnFocus.invoke(editText, show);

} catch (Exception e) {

e.printStackTrace();

}

}

2.光标的产生原理

是在textView的绘制过程中,如果当前textView是Edittext多绘制一个drawable 再每500ms刷新一次绘制流程 造成光标闪烁的效果

在textView的ondraw()方法中有如下代码

Path highlight = getUpdatedHighlightPath();

if (mEditor != null) {

mEditor.onDraw(canvas, layout, highlight, mHighlightPaint, cursorOffsetVertical);

} else {

layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);

}

判断当前的mEditor是否为空 不为空则调用他的ondraw方法,

这里先看下 Editor类的介绍

/**

* Helper class used by TextView to handle editable text views.

*

* @hide

*/

public class Editor {

这个是TextView操纵可编辑Text视图的工具类(可编辑text视图可不就是Edittext)

再看看这个mEditor初始化

/**

* An Editor should be created as soon as any of the editable-specific fields (grouped

* inside the Editor object) is assigned to a non-default value.

* This method will create the Editor if needed.

*

* A standard TextView (as well as buttons, checkboxes...) should not qualify and hence will

* have a null Editor, unlike an EditText. Inconsistent in-between states will have an

* Editor for backward compatibility, as soon as one of these fields is assigned.

*

* Also note that for performance reasons, the mEditor is created when needed, but not

* reset when no more edit-specific fields are needed.

*/

private void createEditorIfNeeded() {

if (mEditor == null) {

mEditor = new Editor(this);

}

}

也就是说只有当可编辑的特殊的字段需要的时候但是未初始化的时候 mEditor便会被创建,但是对于标准的textview 如buttons不会被调用 只有Edittext才会被调用

Edittext的调用流程如下:

TextView初始化调用->setText(text, bufferType);->Edittext重写setText如下:

@Override

public void setText(CharSequence text, BufferType type) {

super.setText(text, BufferType.EDITABLE);

}

->调用createEditorIfNeeded()方法

setText()方法中有如下代码

...

if (type == BufferType.EDITABLE || getKeyListener() != null

|| needEditableForNotification) {

//此处type == BufferType.EDITABLE所以会调用 createEditorIfNeeded();

createEditorIfNeeded();

mEditor.forgetUndoRedo();

Editable t = mEditableFactory.newEditable(text);

text = t;

setFilters(t, mFilters);

InputMethodManager imm = InputMethodManager.peekInstance();

if (imm != null) imm.restartInput(this);

} else if (type == BufferType.SPANNABLE || mMovement != null) {

text = mSpannableFactory.newSpannable(text);

} else if (!(text instanceof CharWrapper)) {

text = TextUtils.stringOrSpannedString(text);

}

...

好了接下来再继续光标的绘制流程

Editor的onDraw()方法如下:

....

if (highlight != null && selectionStart == selectionEnd && mCursorCount > 0) {

drawCursor(canvas, cursorOffsetVertical);

// Rely on the drawable entirely, do not draw the cursor line.

// Has to be done after the IMM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值