停止ScrollView将焦点设置在EditText上

时间:2011-11-11 22:39:16

标签: android focus android-edittext scrollview

Android的ScrollView(当滚动或弹出时)喜欢设置EditText的焦点,当它是它的一个孩子时。滚动然后释放时会发生这种情况。反正有没有阻止这种行为?我已经尝试了几乎所有我能想到的东西以及我在StackOverflow上读过的所有内容。没有什么对我有用。下面是一个示例布局如果您想测试它。我迫切希望阻止这种愚蠢的行为。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<ScrollView 
    android:id="@+id/scrollView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<LinearLayout 
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginRight="50dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    >

    <EditText 
        android:layout_width="fill_parent" 
        android:layout_height="100dp" 
        android:text="TestApp 1"
        />


    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />

    <EditText 
        android:layout_width="fill_parent" 
        android:layout_height="100dp" 
        android:text="Bleh...."
        />

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />
    <EditText 
        android:layout_width="fill_parent" 
        android:layout_height="100dp" 
        android:text="TestApp 1"
        />


    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="MeeEEEEEEEEEEEEE"
        />

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="TestApp 1"
        />



</LinearLayout>
</ScrollView>

</LinearLayout>

5 个答案:

答案 0 :(得分:105)

这很有效。不确定它是否是最佳解决方案。

// SCROLL VIEW HACK
    // BOGUS
    ScrollView view = (ScrollView)findViewById(R.id.scrollView);
    view.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
    view.setFocusable(true);
    view.setFocusableInTouchMode(true);
    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            v.requestFocusFromTouch();
            return false;
        }
    });

答案 1 :(得分:26)

首先,您可以删除ScrollView的父级。 其次,为子项添加焦点选项(每个ScrollView只有一个子项):

android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"

这就是你的xml应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginRight="50dp"
        android:descendantFocusability="beforeDescendants"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/editText_one"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="TestApp 1" />

        <Button
            android:id="@+id/btn_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />

        <Button
            android:id="@+id/btn_two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />

        <Button
            android:id="@+id/btn_three"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />

        <EditText
            android:id="@+id/editText_two"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="Bleh...." />

        <Button
            android:id="@+id/btn_four"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />

        <EditText
            android:id="@+id/editText_three"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="TestApp 1" />

        <Button
            android:id="@+id/btn_five"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />

        <Button
            android:id="@+id/btn_six"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="MeeEEEEEEEEEEEEE" />

        <Button
            android:id="@+id/btn_seven"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TestApp 1" />
    </LinearLayout>

</ScrollView>

另外,请注意您有多个具有相同名称的ID。尝试给他们独特的名字。


如果您只想隐藏软键盘,并让EditText仍然具有焦点,您可以通过在 清单中添加以下属性来实现此活动 >:

android:windowSoftInputMode="stateHidden"

答案 2 :(得分:2)

啊,现在已经很晚了。但我仍然想添加这个解决方案来帮助像我这样的新手。

ScrollView sv = (ScrollView)findViewById(R.id.scrollView);
sv.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            sv.clearFocus();
            return false;
        }
    });

是的,它可以工作,只需将监听器设置为clearfocus。并且它优于requestFocusFromTouch到另一个视图&#39; x,这将导致同样的问题 - 滚动到视图&#39; x&#39;。

答案 3 :(得分:1)

我刚刚添加了一个滚动侦听器,并从活动中获取了焦点视图,并检查了它是否在滚动视图中可见,或者是否滚动到屏幕之外,以及是否滚动到屏幕之外,我只是清除了视图上的焦点

setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
            val focusedView = (context as? FragmentActivity)?.currentFocus
            val viewRect = Rect()
            this.getHitRect(viewRect)

            if(focusedView?.getLocalVisibleRect(viewRect) == false) {
                focusedView.clearFocus()
            }
        }

答案 4 :(得分:0)

如果没有一个答案有效,我建议使用:

yourView.post {
    yourView.requestFocus()
    scrollView.scrollY = 0
}

这样,如果您需要滚动开始,scrollView 将返回 scroll 0。

如果不是那么您需要将其更改为正确的坐标