Mih*_*nov 5 keyboard android android-layout
我有一个全屏横向应用程序(Cocos2d-x/NDK),带有一个输入字段,我在运行时设置的位置如下
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mInstance.mEditText.getLayoutParams();
params.topMargin = (int)newY;
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
mInstance.mEditText.setLayoutParams(params);
Run Code Online (Sandbox Code Playgroud)
它在大多数设备上运行都很酷,但我有一种设备,其中软键盘动态增长,上面有“建议”行。那就是奇怪的事情发生的时候。
如果我的 EditText 位于屏幕顶部的某个位置,即它的矩形不与键盘相交,则不会发生任何变化,EditText 保持在原来的位置,一切正常。但是,如果我的 EditText 位于屏幕中间,因此键盘将与它重叠,它就会开始向上移动(带有动画)。
我成功地使用 SOFT_INPUT_ADJUST_PAN 来确定键盘高度(通过getWindowVisibleDisplayFrame调用之间的差异),因此我不能仅通过设置adjustmentNothing标志来禁用平移,我将坚持使用adjustmentPan。
问题是,当调整软键盘大小(对于建议行)时,我无法理解我的视图位置到底做了什么。在我的 onGlobalLayout 中我尝试观看:
- TextView getY(),
- TextView getTranslationY(),
- TextView RelativeLayout params (topMargin, bottomMargin),
- TextView getLocationOnScreen,
- TextView getGlobalVisibleRect top & bottom,
- Activity getWindowVisibleDisplayFrame rect top & bottom.
Run Code Online (Sandbox Code Playgroud)
以上内容均未更改!但 TextView 无论如何都是向上移动的。我相信在软键盘出现后,视图树中的某个地方应用了一些偏移。但是为什么 getLocationOnScreen 不显示这个呢?为什么 getGlobalVisibleRect 也不知道任何有关位置变化的信息?
我想为我的 EditText 设置确切的位置,所以即使我无法阻止它向上移动(设置adjustmentPan标志的权衡),至少我需要知道它向上移动了多少,以应用反向转换。
我尝试了一个非常hacky的解决方法:在我的EditText beforeTextChanged()方法中,我将TextView的布局topMargin设置为0,以确保当建议行出现时,它不会移动我的TextView,因为它不再重叠。然后在 onGlobalLayout() 中我恢复正确的 EditText 位置。它有效,但我不喜欢这种方式,而且它还会导致我的文本闪烁。
一些代码可以更好地理解我正在做的事情。
private void showKeyboard(final boolean show) {
final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (show) {
mEditText.requestFocus();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
imm.showSoftInput(mEditText, 0);
}
}, 50);
mVisible = true;
} else {
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
mEditText.clearFocus();
mVisible = false;
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.native_keyboard);
mLayout = findViewById(R.id.keyboard_layout);
mEditText = (EditText) findViewById(R.id.keyboard_input);
mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
mEditText.setInputType(mEditText.getInputType() | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS | EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE);
mInitialFrame = getVisibleFrame();
mPreviousFrame = mInitialFrame;
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final int kbAssumedH = 100;
Rect currentFrame = getVisibleFrame();
final int dResize = (int) (mPreviousFrame.height() - currentFrame.height());
if (mWasShown && isVisible() && dResize != 0) {
NativeKeyboard.onKeyboardResized();
}
mPreviousFrame = currentFrame;
if (isVisible() && (mInitialFrame.height() - currentFrame.height() > kbAssumedH)) {
if (!mWasShown) {
NativeKeyboard.onKeyboardDidShow();
mWasShown = true;
}
} else {
if (mWasShown) {
NativeKeyboard.onKeyboardDidHide();
mWasShown = false;
}
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
这就是我获取不与键盘重叠的当前窗口空间的方法:
public static synchronized android.graphics.Rect getVisibleFrame() {
View rootView = mInstance.getWindow().getDecorView();
android.graphics.Rect r = new android.graphics.Rect();
rootView.getWindowVisibleDisplayFrame(r);
return r;
}
Run Code Online (Sandbox Code Playgroud)
这是我用来设置 EditText 位置的方法。一旦建议行出现后,我的 EditText 视觉上会相对于我在此处作为 Y 参数传递的位置向上移动(并且移动是永久性的,即我可以使用新位置调用 setRect,并且它也将被移动)
public static synchronized void setRect(final float x, final float y, final float w, final float h) {
if (mInstance != null) {
Cocos2dxHelper.runOnUIThread(new Runnable() {
@Override
public void run() {
mInstance.mEditText.setX((int) x);
float height = mInstance.mEditText.getHeight();
mInstance.mEditText.setWidth((int) w);
float yCenter = y + h / 2;
float newY = yCenter - height / 2.f;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mInstance.mEditText.getLayoutParams();
params.topMargin = (int)newY;
params.width = (int)w;
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
mInstance.mEditText.setLayoutParams(params);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了 4 种不同的设备(3 部手机和 1 部平板电脑),仅在 Acer Liquid Jade Z 4.4.4 上出现问题。
提前致谢。
好吧,我没能抓住转变本身。相反,在我的特定情况下可行的解决方法如下:
添加新的不可见对话框,仅将其用于getWindowVisibleDisplayFrame,因此当键盘显示/隐藏时您将获得所需的一切。
...并且肯定您现在希望主(可见)对话框使用 SOFT_INPUT_ADJUST_NOTHING ,如果您不再需要它的 displayFrame ,为什么不呢?因此,在您看来,没有任何隐藏的、不明显的变化适用于任何事物。
就这么简单。希望能帮助到你。