簡単な入力フォームがあります。これは、ScrollView内にEditTextsがある垂直のLinearLayoutです。
<ScrollView Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<LinearLayout Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical">
<LinearLayout Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:padding="10dip"
Android:gravity="center_vertical"
Android:orientation="horizontal">
<TextView style="@style/Text"
Android:text="Name"/>
<EditText style="@style/EditBox"/>
</LinearLayout>
<View style="@style/Divider"/>
<LinearLayout Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:padding="10dip"
Android:gravity="center_vertical"
Android:orientation="horizontal">
<TextView style="@style/Text"
Android:text="Password"/>
<EditText style="@style/EditBox"/>
</LinearLayout>
...
</LinearLayout>
</ScrollView>
ユーザーがフォームをスクロールすると、自動的にフォーカスが表示されているEditTextに移動します。そのような動作を無効にして、常に現在タッチで選択されているEditTextにフォーカスを維持することは可能ですか?
これは機能である可能性があることを理解していますが、無効にする必要があります。
ありがとう!
これに対する私の解決策を共有したいと思っただけです。他の回答のコメントの一部には、この動作をオーバーライドできないと記載されていますが、これは正しくありません。この動作は、onRequestFocusInDescendants()
メソッドをオーバーライドするとすぐに停止します。したがって、これを行うには、ScrollView拡張機能を作成するだけです。
public class NonFocusingScrollView extends ScrollView {
public NonFocusingScrollView(Context context) {
super(context);
}
public NonFocusingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonFocusingScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
}
これで完了です。 ScrollView
は、あなたのフォーカスを混乱させることはもうありません。
私もそのような問題を抱えていました。私を助けた唯一の方法は、スクロールビューを拡張して、隣人をオーバーライドすることです
_@Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
_
または
_@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
_
ただし、次のようにViewGroup.requestChildFocus(View child, View focused)
メソッドをオーバーライドします。
_ @Override
public void requestChildFocus(View child, View focused) {
// avoid scrolling to focused view
// super.requestChildFocus(child, focused);
}
_
私にとってうまくいったのは、@ dmonの回答と@wajの回答を組み合わせることでした。
ScrollView内でEditTextsのみを処理している場合は、onRequestFocusInDescendants()
のオーバーライドのみが適切に機能しましたが、複数のビュータイプを追加し始めたときは、うまく機能しませんでした。
getFocusables()
のオーバーライドのみではまったく機能しませんでした。
onRequestFocusInDescendants()
AND getFocusables()
の両方をオーバーライドすると、すべてのシナリオで美しく機能するようです。
public class FixedFocusScrollView extends ScrollView {
public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public FixedFocusScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixedFocusScrollView(Context context) {
super(context);
}
@Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
}
私はここに投稿されたすべての解決策を試しましたが、特定のAndroid=バージョンで機能しないか、タッチモードと非タッチモードを切り替えるとき(ボタンをクリックするか、トラックパッド)。
私はついにメソッドgetFocusables
をオーバーライドすることがトリックをすることを発見しました:
public class FixedFocusScrollView extends ScrollView {
public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public FixedFocusScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixedFocusScrollView(Context context) {
super(context);
}
@Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
}
ソースから問題を切り取ってみてください(edit:つまり、XMLファイルに移動します)。
まず、そのためにはフォーカス可能な要素が必要です。そのスクロールに含まれるすべてのフォーカス可能な要素を非フォーカス可能な要素にします。ビューがインフレートされて表示された後、フォーカス可能にします。
Android:focusable="false"
Android:focusableInTouchMode="false"
私の問題に役立つ別の簡単な解決策を見つけました。
私はScrollView
を取得しました。上部にEditText
があり、その後にTextViews、RatingBars、Buttonsの大きなリストがあります。ボタンはAlertDialogを起動し、ポップアップすると、ScrollView
が一番上に移動し、フォーカスがあるEditText
に移動します。
それを解決するために、ActivityのonClick
メソッドでrequestFocusFromTouch()
をクリックしたビュー(この場合はボタン)に設定します。
public void onClick(View v) {
v.requestFocusFromTouch();
...
}
Button
をクリックすると、ScrollView
が移動し、そのButton
が画面の中央に配置されます。
お役に立てば幸いです。
今日私に起こったのは、基本的に私はいくつかの既存のビューの間にプログラムでビューを追加し、Scrollが自動的に移動してそのビューに焦点を合わせていたことです。私がやったことは、次のとおりです。
container.setFocusable( false );
このような動作には、nextFocusUpおよびnextFocusDownを使用します。
<EditText
Android:id="@+id/my_edit_text"
Android:nextFocusDown="@id/my_edit_text"
Android:nextFocusUp="@id/my_edit_text"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
</EditText>