ListViewにいくつかのEditTextフィールドがあります。 EditTextフィールドの1つをタップすると、キーボードが(必要に応じて)表示されますが、タップしたEditTextフィールドはフォーカスを失います。さまざまなInputMethodManagerメソッドを使用して、キーボードをビューで開始しようとしました(実際に解決するのではなく、問題を回避するために)が、機能しませんでした-アクティビティが表示されたときにキーボードが表示されていません.
EditTextのタイプはnumber
で、キーボードがスライドしているときは数字キーボードですが、スライドが終了してEditTextがフォーカスを失うと、アルファベットのキーボードに変わります(これにより、EditTextもはやフォーカスがありません)。
私の質問は次のとおりです。
1)どうすればEditTextフィールドを選択し、その後ソフトキーボードをスライドインできますかnot EditTextにフォーカスを失いますか?
...失敗した...
2)キーボードをスライドさせて表示する必要がないようにキーボードを表示するにはどうすればよいですか(したがって、好ましくない動作を回避できますか)。
私のマニフェストにはAndroid:windowSoftInputMode="stateAlwaysVisible"
が、EditTextをタップするまでキーボードは表示されません。 「stateAlwaysVisible」属性のこの無視は、エミュレータでのみ発生するようです-プロビジョニングされたデバイスでは、上記の質問番号2がデバイスで動作しますが、エミュレータでは動作しません。
あなたが提供できる助けをありがとう!
これが私がやった方法です。 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();
}
});
}
}
}
};
上記のコードは、キーボードのポップアップに適しています。ただし、音声テキスト変換ポップアップは検出しません。
AndroidManifest.xmlを変更する必要があります
リストビューを保持するアクティビティにAndroid:windowSoftInputMode = "adjustPan"を追加します。これで問題が解決します。
<activity Android:name=".MyEditTextInListView"
Android:label="@string/app_name"
Android:windowSoftInputMode="adjustPan">
よろしく
私の場合、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();
}
}
ListView内のeditTextがgetViewメソッドでこの方法でViewを膨らませていることを確認してください。
if (convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
parent, false);
編集:この作品は、一部の携帯電話では、上記のMr.Frankの回答をすべて使用しているわけではありません。
AndroidManifest.xmlでは、ビューを含むアクティビティでadjustNothingを使用します
<activity
Android:name=".ActivityName"
Android:windowSoftInputMode="adjustNothing">
ハードウェアキーボードが常に表示されるデバイスでこのコードをテストする必要があります。ここでも動作が発生する場合があります。
これを回避するために、キーボードを常に表示することができます。
https://groups.google.com/forum/#!topic/Android-developers/FyENeEdmYC
理論的には、独自のAndroidキーボードを作成する必要があります(ただし、ベースとしてストックAndroidキーボード)を使用します): Android:How toキーパッドを常に表示しますか?
XamarinまたはXamarin.Formsを使用してここに来る人のために:
私も同じ問題を抱えていましたが、Android 5.x-8.1を含むすべての新しいバージョンでうまくいきました。
明らかにsheltondは正しいと言った:
私の場合、ListViewのサイズが変更されると、すべてのリストアイテムが再作成されます(つまり、表示されている各リストアイテムに対してgetView()が再度呼び出されるため)。
私のリストビューもサイズ変更されていて、いいえ、Frank s windowSoftInputMode="adjustPan"
は、キーボードがリストビューを部分的に画面から移動することを意味するため、私には選択肢ではありませんでした。
数時間のフォーカスデバッグの後、Xamarin Forms ListViewのセルキャッシュ戦略を設定するだけで済みました。
から
CachingStrategy="RecycleElement"
に
CachingStrategy="RetainElement"
これにより、セルの再作成が停止します。ただし、これにより、巨大なリストのパフォーマンスが低下し、メモリが大量に消費される可能性があります。注意してください。
リストビューまたはEditTextを保持するアクティビティにAndroid:windowSoftInputMode = "adjustResize"を追加します。これで問題が解決します。
<activity Android:name=".MainActivity"
Android:windowSoftInputMode="adjustResize">
</activity>
私の場合、キーボードが表示されたときにルート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)
を直接呼び出しても機能しませんでした。