Stop ScrollView from auto-scrolling to an EditText

后端 未结 21 1288
长发绾君心
长发绾君心 2020-11-30 23:17

Seems to be a common problem without a great solution that I have found. Goal is to stop a ScrollView from auto-scrolling to an EditText (or any vi

相关标签:
21条回答
  • 2020-11-30 23:20

    thomas88wp answer, https://stackoverflow.com/a/6486348/528746 worked for me. But I had two problems: 1. When scrolling, I wanted to hide the keyboard
    2. I had lots of EditText views and didn't want to write it for each one of them
    (I do getActivity() since I'm writing this inside a Fragment and not an activity)

        ScrollView scroll = (ScrollView)view.findViewById(R.id.layout_scroll);
        scroll.setOnTouchListener(new OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // Check if the view with focus is EditText
                if (getActivity().getCurrentFocus() instanceof EditText)
                {
                    EditText ed = (EditText)getActivity().getCurrentFocus();
                    if (ed.hasFocus()) {
    
                        // Hide the keyboard
                        InputMethodManager inputManager = (InputMethodManager)
                                getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); 
                        inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),
                                InputMethodManager.HIDE_NOT_ALWAYS);
                        // Clear the focus
                        ed.clearFocus();
                    }
                }
                return false;
            }
    
        });
    
    0 讨论(0)
  • 2020-11-30 23:21

    Just create an empty view at the top of linearlayout

    <View android:layout_width="fill_parent" android:id="@+id/focus_view" android:layout_height="0dp" android:focusable="true" android:focusableInTouchMode="true"><requestFocus/></View>
    

    Single line solves the problem

    0 讨论(0)
  • 2020-11-30 23:22

    I had the same problem. There's one trick that I'm using to deal with this problem:

    public void onClick(View v) {
        button.requestFocusFromTouch(); //prevents from loosing focus and scrolling view down
        ....
    }
    
    0 讨论(0)
  • 2020-11-30 23:24

    Create a custom ScrollView (create a class and have it extend HorizontalScrollView) and make a getter setter for scrollable. Then override computeScrollDeltaToGetChildRectOnScreen.

    How it works: Every time android has an edit text or something in focus that is off screen it calls method computeScrollDeltaToGetChildRectOnScreen to bring it into view. If you Override it and return 0 when it is disabled than it will not scroll...

    So you will have A custom scroll view like this:

        public class TrackableHorizontalScrollView extends HorizontalScrollView {
    
    
        // true if we can scroll (not locked)
        // false if we cannot scroll (locked)
        private boolean mScrollable = true;
    
        public TrackableHorizontalScrollView(Context context) {
            super(context);
        }
    
        public TrackableHorizontalScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public TrackableHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public void setScrollingEnabled(boolean enabled) {
            mScrollable = enabled;
        }
    
        public boolean isScrollable() {
            return mScrollable;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // if we can scroll pass the event to the superclass
                    if (mScrollable) return super.onTouchEvent(ev);
                    // only continue to handle the touch event if scrolling enabled
                    return mScrollable; // mScrollable is always false at this point
                default:
                    return super.onTouchEvent(ev);
            }
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            // Don't do anything with intercepted touch events if
            // we are not scrollable
            if (!mScrollable) return false;
            else return super.onInterceptTouchEvent(ev);
        }
    
        @Override
        public void scrollTo(int x, int y){
            if (!mScrollable) return;
            super.scrollTo(x, y);
        }
    
    
        //Custom smooth scroll method since norm is final and cannot be overridden
        public final void smooothScrollToIfEnabled(int x, int y){
             if (!mScrollable) return;
             smoothScrollTo(x, y);
        }
    
        @Override
        protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect rect){
            if (!mScrollable) return 0;
            return super.computeScrollDeltaToGetChildRectOnScreen(rect);
        }
    
    
    }
    

    You can use this inside your XML like this:

    <com.your.package.ui.widget.TrackableHorizontalScrollView
                android:id="@+id/wi_et_credit_scroller"
                android:layout_toRightOf="@id/wi_et_credit_iv"
                android:layout_width="fill_parent"
                android:scrollbars="none"
                android:layout_height="wrap_content"
                android:paddingRight="5dp"
                android:layout_gravity="center_vertical">
    
    <!--Whatever you have inside the scrollview-->
    
    </com.your.package.ui.widget.TrackableHorizontalScrollView>
    
    0 讨论(0)
  • 2020-11-30 23:24

    The best Solution is to add focus options for the child of your scrollview :

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

    Then your xml file will look like :

    <?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" />
    
            <EditText
                android:id="@+id/editText_two"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:text="TestApp 2" />
    
           <EditText
                android:id="@+id/editText_three"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:text="TestApp 3" />
    
    
        </LinearLayout>
    
    </ScrollView>
    
    0 讨论(0)
  • 2020-11-30 23:24

    I often has this problem when my apps handle orientation change.

    In that case I use the following kind of code:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // to avoid the scrollview to scroll to this element automatically
        mEditTextSearch.setFocusable(false);
        // Get the saved scroll position
        final int scrolly = savedInstanceState.getInt("scrolly");
        mScrollView.post(new Runnable() {
            @Override
            public void run() {
                mScrollView.scrollTo(0, scrolly);
                // Restore the initial state of the EditText
                mEditTextSearch.setFocusable(true);
                mEditTextSearch.setFocusableInTouchMode(true);
                mEditTextSearch.setClickable(true);
            }
        });
        ...
    }
    
    0 讨论(0)
提交回复
热议问题