android-当软键盘出现时,它使我的EditText字段失去焦点
我在ListView中有几个EditText字段。 当我点击EditText字段之一时,键盘滑入视图(应如此),但是我点击的EditText字段失去了焦点。 我尝试使用各种InputMethodManager方法使键盘在视图中启动(以解决问题而不是真正解决问题),但这没有用-当活动出现时,键盘不在视图中。
EditText的类型为2687432202299900900928,当键盘滑入时,它是数字键盘,但是当滑入并完成EditText失去焦点时,它将更改为字母键盘(这增强了EditText不再具有焦点的想法)。 。
我的问题是:
1)如何选择我的EditText字段并随后滑入软键盘不会使我的EditText失去焦点?
...失败了...
2)我如何才能使键盘在视野范围内启动,从而不必滑入键盘(从而避免出现我讨厌的行为)?
我的清单中确实包括android:windowSoftInputMode="stateAlwaysVisible",但是直到我点击EditText才出现键盘。 对“ stateAlwaysVisible”属性的忽略似乎仅发生在模拟器中-在我配置的设备上,很荣幸能使上面的问题2在设备上起作用,但在模拟器中不起作用。
感谢您的任何帮助,您可以提供!
10个解决方案
121 votes
您需要更改您的AndroidManifest.xml
在持有列表视图的活动中添加android:windowSoftInputMode =“ adjustPan”。这样可以解决您的问题。
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan">
问候
Frank answered 2020-01-04T07:01:00Z
15 votes
这是我的方法。 当您触摸EditText在其中键入文本时,将多次调用//
private final int minDelta = 300; // threshold in ms
private long focusTime = 0; // time of last touch
private View focusTarget = null;
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
long t = System.currentTimeMillis();
long delta = t - focusTime;
if (hasFocus) { // gained focus
if (delta > minDelta) {
focusTime = t;
focusTarget = view;
}
}
else { // lost focus
if (delta <= minDelta && view == focusTarget) {
focusTarget.post(new Runnable() { // reset focus to target
public void run() {
focusTarget.requestFocus();
}
});
}
}
}
};。 顺序为:
如果焦点在另一个视图上,那么该视图将失去焦点
目标获得关注
软键盘弹出。
这会使目标失去焦点
代码检测到这种情况并调用target.requestFocus()
由于Android的废话,最左,最顶的视图获得了关注
由于调用了requestFocus,最左侧的视图失去了焦点
目标终于获得关注
//
private final int minDelta = 300; // threshold in ms
private long focusTime = 0; // time of last touch
private View focusTarget = null;
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
long t = System.currentTimeMillis();
long delta = t - focusTime;
if (hasFocus) { // gained focus
if (delta > minDelta) {
focusTime = t;
focusTarget = view;
}
}
else { // lost focus
if (delta <= minDelta && view == focusTarget) {
focusTarget.post(new Runnable() { // reset focus to target
public void run() {
focusTarget.requestFocus();
}
});
}
}
}
};
上面的代码对于键盘弹出窗口非常有效。 但是,它不会检测到语音到文本的弹出窗口。
SoloPilot answered 2020-01-04T07:00:31Z
10 votes
就我而言,这是因为ListView调整大小时,它会重新创建所有列表项(即,它为每个可见列表项再次调用getView())。
因为EditText在我从getView()返回的布局中,所以这意味着它与之前具有焦点的EditText实例不同。 第二个后果是,当软键盘出现或消失时,我发现我丢失了EditText的内容。
因为我希望我的视图保持完全可访问性(即,我希望调整视图的大小而不是隐藏在键盘窗口的后面,而某些部分无法访问),所以我无法使用弗兰克的答案,否则这似乎是最好的方法。
我通过在EditText上使用OnFocusChangeListener记录焦点丢失时的时间戳,然后在重新创建列表项时在getView()中解决了此问题,如果当前时间在焦点丢失时的某个阈值之内,请调用requestFocus( ),以将其返回给相关的EditText。
您还可以从那时的EditText的先前实例中获取文本,并将其传输到新实例。
private class MyAdapter extends ArrayAdapter
implements OnFocusChangeListener
{
private EditText mText;
private long mTextLostFocusTimestamp;
private LayoutInflater mLayoutInflater;
public MyAdapter(Context context, int resource, int textResourceId, ArrayList data, LayoutInflater li) {
super(context, resource, textResourceId, data);
mLayoutInflater = li;
mTextLostFocusTimestamp = -1;
}
private void reclaimFocus(View v, long timestamp) {
if (timestamp == -1)
return;
if ((System.currentTimeMillis() - timestamp) < 250)
v.requestFocus();
}
@Override public View getView (int position, View convertView, ViewGroup parent)
{
View v = mLayoutInflater.inflate(R.layout.mylayout, parent, false);
EditText newText = (EditText) v.findViewById(R.id.email);
if (mText != null)
newText.setText(mText.getText());
mText = newText;
mText.setOnFocusChangeListener(this);
reclaimFocus(mText, mTextLostFocusTimestamp);
return v;
}
@Override public void onFocusChange(View v, boolean hasFocus) {
if ((v == mText) && !hasFocus)
mTextLostFocusTimestamp = System.currentTimeMillis();
}
}
sheltond answered 2020-01-04T07:01:40Z
1 votes
您应该在始终可见硬件键盘的设备上测试此代码。 该行为也可能在这里发生。
为了避免这种情况,您可以始终使键盘可见。.但是,通过此线程可以看到这并不容易:
[https://groups.google.com/forum/#!topic/android-developers/FyENeEdmYC0]
从理论上讲,您可能必须按如下所述创建自己的Android键盘(尽管使用普通的Android键盘作为基础):Android:如何使键盘始终可见?
neteinstein answered 2020-01-04T07:02:14Z
1 votes
在AndroidManifest.xml中,在包含视图的活动中使用AdjustNothing
android:name=".ActivityName"
android:windowSoftInputMode="adjustNothing">
Orlay Garcia Duconge answered 2020-01-04T07:02:33Z
1 votes
如果listView内的editText仅确保您使用这种方法在getView方法中为View充气。
if (convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
parent, false);
编辑:这项工作适用于某些手机,但并非全部使用上面弗兰克先生的答案。
Samer Kador answered 2020-01-04T07:02:58Z
0 votes
这个家伙有同样的问题,而且还有更多。 他通过使用ScrollView和LinearLayout而不是ListView解决了该问题。
Martin Stone answered 2020-01-04T07:03:18Z
0 votes
在包含列表视图或EditText的活动中添加android:windowSoftInputMode =“ adjustResize”。 这样可以解决您的问题。
android:windowSoftInputMode="adjustResize">
Jibin Anto answered 2020-01-04T07:03:38Z
0 votes
对于那些使用Xamarin或Xamarin.Forms来到这里的人:
我也遇到了同样的问题,但仅适用于Android 5.x-包括8.1在内的所有较新版本都运行良好。
谢尔顿说的很显然是对的:
就我而言,这是因为ListView调整大小时,它会重新创建所有列表项(即,它为每个可见列表项再次调用getView())。
我的列表视图也正在调整大小,不,对于我来说,设置windowSoftInputMode="adjustPan"的Franks解决方案不是我的选择,因为这意味着键盘会将列表视图部分移出屏幕。
经过数小时的焦点调试之后,我要做的就是设置Xamarin Forms ListView的单元格缓存策略:
从
CachingStrategy="RecycleElement"
至
CachingStrategy="RetainElement"
这将阻止重新创建单元。 但是,这对于大型列表可能会导致性能下降和高内存消耗。 意识到。
Waescher answered 2020-01-04T07:04:34Z
0 votes
就我而言,我曾打电话给root_scrollview.scrollTo(0,root_container.bottom)当出现键盘时,在我的根ScrollView上。我用
login_scrollview.post(new Runnable() {
@Override
public void run() {
root_scrollview.scrollTo(0,root_container.bottom)
}
});
其中,root_container是root_scrollview的直接子级。 这为我解决了问题。
注意:直接呼叫root_scrollview.scrollTo(0,root_container.bottom)无法正常工作。
Ismail Shaikh answered 2020-01-04T07:05:03Z