![](/img/trans.png)
[英]How to lose the focus of a edittext when "done" button in the soft keyboard is pressed?
[英]When the soft keyboard appears, it makes my EditText field lose focus
我在 ListView 中有一些 EditText 字段。 當我點擊 EditText 字段之一時,鍵盤會滑入視圖(應該如此),但我點擊的 EditText 字段失去焦點。 我嘗試使用各種 InputMethodManager 方法使鍵盤在視圖中啟動(為了解決問題而不是真正解決它),但這不起作用 - 當 Activity 出現時鍵盤不在視圖中。
EditText 的類型是number
,當鍵盤滑入時,它是一個數字鍵盤,但是當它完成滑動並且 EditText 失去焦點時,它變為字母鍵盤(這加強了 EditText 不再有焦點的想法) .
我的問題是這些:
1) 如何使我的 EditText 字段的選擇和軟鍵盤的后續滑入不會使我的 EditText 失去焦點?
……失敗了……
2) 我怎樣才能讓鍵盤從視野中開始,這樣它就不必滑入(從而避免我覺得如此令人反感的行為)?
我的清單確實包括android:windowSoftInputMode="stateAlwaysVisible"
,但在我點擊 EditText 之前鍵盤不會出現。 這種對 'stateAlwaysVisible' 屬性的忽略似乎只發生在模擬器中 - 在我配置的設備上,它很榮幸,所以上面的問題 2 確實適用於設備......但不適用於模擬器。
感謝您的任何幫助,您可以提供!
您需要在 AndroidManifest.xml 中進行更改
在持有列表視圖的活動中添加 android:windowSoftInputMode="adjustPan"。 這將解決您的問題。
<activity android:name=".MyEditTextInListView"
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan">
問候
這是我如何做到的。 當您觸摸EditText
以在其中鍵入文本時, onFocusChangeListener()
會被多次調用。 順序是:
目標終於獲得焦點
////////////////////////////////////////////////////////////////// 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(); } }); } } } };
上面的代碼適用於鍵盤彈出窗口。 但是,它不會檢測到語音到文本的彈出窗口。
在我的情況下,發生這種情況是因為當 ListView 調整大小時,它會重新創建所有列表項(即它為每個可見列表項再次調用 getView())。
因為 EditText 位於我從 getView() 返回的布局內,這意味着它是 EditText 的一個不同實例,而不是以前具有焦點的實例。 第二個后果是當軟鍵盤出現或消失時,我發現我丟失了 EditText 的內容。
因為我希望我的視圖保持完全可訪問(即我希望它被調整大小而不是隱藏在鍵盤窗口后面,某些部分不可訪問),我不能使用弗蘭克的答案,否則這似乎是最好的方法。
我通過在 EditText 上使用 OnFocusChangeListener 記錄焦點丟失時的時間戳來解決這個問題,然后在重新創建列表項時在 getView() 中,如果當前時間在焦點丟失時的某個閾值內,請調用 requestFocus( ) 將其返回給有問題的 EditText。
您還可以在那時從 EditText 的前一個實例中獲取文本並將其傳輸到新實例。
private class MyAdapter<Type> extends ArrayAdapter<String>
implements OnFocusChangeListener
{
private EditText mText;
private long mTextLostFocusTimestamp;
private LayoutInflater mLayoutInflater;
public MyAdapter(Context context, int resource, int textResourceId, ArrayList<String> 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();
}
}
在 AndroidManifest.xml 中,在包含視圖的活動中使用 adjustNothing
<activity
android:name=".ActivityName"
android:windowSoftInputMode="adjustNothing">
如果 listView 中的 editText 只是確保使用這種方式在 getView 方法中膨脹 View 。
if (convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
parent, false);
編輯:這項工作適用於某些手機,並非所有我都使用上面 Mr.Frank 的答案。
您應該在硬件鍵盤始終可見的設備上測試此代碼。 這種行為也可能發生在這里。
為避免這種情況,您可以讓鍵盤始終可見。
https://groups.google.com/forum/#!topic/android-developers/FyENeEdmYC0
從理論上講,您可能需要創建自己的 Android 鍵盤(盡管使用 Android 鍵盤作為基礎),如下所述: Android:如何使鍵盤始終可見?
在包含列表視圖或 EditText 的活動中添加 android:windowSoftInputMode="adjustResize"。 這將解決您的問題。
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
</activity>
對於那些帶着 Xamarin 或 Xamarin.Forms 來到這里的人:
我也遇到了同樣的問題,但僅限於 Android 5.x - 包括 8.1 在內的所有較新版本都運行良好。
顯然,謝爾頓說得對:
在我的情況下,發生這種情況是因為當 ListView 調整大小時,它會重新創建所有列表項(即它為每個可見列表項再次調用 getView())。
我的列表視圖也在調整大小,不,弗蘭克設置windowSoftInputMode="adjustPan"
的解決方案對我來說不是選擇,因為這意味着鍵盤將列表視圖部分移出屏幕。
經過數小時的焦點調試后,我所要做的就是設置 Xamarin Forms ListView 的單元格緩存策略:
從
CachingStrategy="RecycleElement"
到
CachingStrategy="RetainElement"
這將阻止重新創建單元格。 但是,這可能會導致巨大的列表性能不佳和內存消耗高。 意識到。
就我而言,當鍵盤出現時,我在我的根 ScrollView 上調用了root_scrollview.fullScroll(View.FOCUS_DOWN)
。 我用
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)
不起作用。
這家伙有同樣的問題,而且還有更多。 他通過使用 ScrollView 和 LinearLayout 而不是 ListView 解決了這個問題。
我相信失去對鍵盤顯示或隱藏的關注不是預期的行為,並且應該是(或應該是)報告的 Android 問題。
但是現在已經晚了,10年后OP遇到了!
在我的情況下,開關的缺點SOFT_INPUT_ADJUST_RESIZE
到SOFT_INPUT_ADJUST_PAN
勝過不失去焦點的優勢。
為什么? ADJUST_RESIZE
是官方首選的方法,因為ADJUST_PAN
阻止部分視圖並可能阻止滾動。
但是由於早先對這個問題的回答,我對ListView
強烈的懷疑。
為了證明我的懷疑,我花了一天時間將一個復雜的基於ListView
的編輯器轉換為RecyclerView
。
我可以確認軟鍵盤狀態更改不再影響EditText
焦點,即使我正在使用ADJUST_RESIZE
。
我知道看起來很痛苦 - 但也許最終結果比子分類或棘手的解決方法更好?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.