説明
これと同じ問題があり、次の変更で修正しました。彼らのトリックは、他の子ビューがそれを必要としないときはいつでも、親スクロール ビューがフォーカスを取得できるようにすることでした。これが機能するには、スクロールビューがクリック可能でフォーカス可能でなければなりません。ScrollView はかなり複雑なスクロール動作のためにこれらを活用する必要があるため、これはonTouchEvent
orを使用するよりも優れています。onInterceptTouchEvent
コードの変更
まず、レイアウト ファイルで、これらの属性をスクロールビューに追加します。
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
次に、コードでこれらのリスナーをスクロールビューに追加します。
scrollableContent.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
onClickAway();
}
}
});
//this second listener is probably unnecessary but I put it in just in case there are weird edge cases where the scrollView is clicked but failed to gain focus
scrollableContent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onClickAway();
}
});
最後に、ユーザーがフォームのフィールドから離れた場所をクリックしたときに必要な動作を実装します。
/**
* Invoked when something is clicked that is not otherwise listening for click events, like when
* the user clicks outside of an EditText view.
*/
protected void onClickAway() {
//hide soft keyboard
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
結果
これらの変更により、スクロールビューはクリックされるたびにフォーカスを取得し、それに応じてキーボードが非表示になります。キーボードを必要とする他のフィールドをクリックすると、それらが優先され、キーボードは変更されない (つまり、開いたままになる) ことに注意してください。また、代わりに、XML 属性とリスナーを scrollView の子 ViewGroup に追加することもできます。テストはしていませんが、同様に機能すると確信しています。