HorizontalScrollView: auto-scroll to end when new Views are added?

后端 未结 9 1133
鱼传尺愫
鱼传尺愫 2020-11-28 06:37

I have a HorizontalScrollView containing a LinearLayout. On screen I have a Button that will add new Views to the LinearLayout at runtime, and I\'d like the scroll view to

相关标签:
9条回答
  • 2020-11-28 06:56

    I agree with @monxalo and @granko87 that the better approach is with a listener instead of making an assumption that the layout will be complete if we let some arbitrary amount of time pass.

    In case, like me, you don't need to use a custom HorizontalScrollView subclass you can just add an OnLayoutChangeListener to keep things simple:

    mTagsScroller.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            mTagsScroller.removeOnLayoutChangeListener(this);
            mTagsScroller.fullScroll(View.FOCUS_RIGHT);
        }
    });
    
    0 讨论(0)
  • 2020-11-28 07:00

    Use the View method smoothScrollTo

    postDelayed(new Runnable() {
        public void run() {
           scrollView.smoothScrollTo(newView.getLeft(), newView.getTop());
     }
     }, 100L);
    

    You need to put in a runnable so you give time to the layout process to position the new View

    0 讨论(0)
  • 2020-11-28 07:06

    I think the best approach is the one posted by monxalo because you can not know how much time will it take until the layout is done. I tried it and it works perfectly. The only difference is, that I added only one row to my custom horizontal scroll view:

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        this.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
    }
    
    0 讨论(0)
  • 2020-11-28 07:07

    This is what I did.

    //Observe for a layout change    
    ViewTreeObserver viewTreeObserver = yourLayout.getViewTreeObserver();
       if (viewTreeObserver.isAlive()) {
         viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    yourHorizontalScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
                }
         });
       }
    
    0 讨论(0)
  • 2020-11-28 07:09

    The child View may not be immediately added in a ViewGroup. So it is required to post a Runnable which will run after other pending tasks are completed.

    So after adding View, use:

    horizontalScrollView.post(new Runnable() {
        @Override
        public void run() {
            horizontalScrollView.fullScroll(View.FOCUS_RIGHT);
        }
    });
    
    0 讨论(0)
  • 2020-11-28 07:09

    This is my way for 3 ImageViews in kotlin:

    var p1 = true; var p2 = false; var p3 = false
    val x = -55
    val handler = Handler()
    handler.postDelayed(object : Runnable {
        override fun run() {
    
            if (p1){
                mainView.picsScrollViewID.smoothScrollTo(mainView.bigPic1ID.x.toInt() + x, 0)
                p1 = false
                p2 = true
                p3 = false
            }
            else if(p2){
                mainView.picsScrollViewID.smoothScrollTo(mainView.bigPic2ID.x.toInt() + x, 0)
                p1 = false
                p2 = false
                p3 = true
            }
            else if(p3){
                mainView.picsScrollViewID.smoothScrollTo(mainView.bigPic3ID.x.toInt() + x, 0)
                p1 = true
                p2 = false
                p3 = false
            }
            handler.postDelayed(this, 2000)
        }
    }, 1400)
    
    0 讨论(0)
提交回复
热议问题