Stop ScrollView from auto-scrolling to an EditText

后端 未结 21 1318
长发绾君心
长发绾君心 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条回答
  •  Happy的楠姐
    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:

    
    
    
    
    
    

提交回复
热议问题