Android:ScrollView强制到底

时间:2010-06-20 18:20:54

标签: android android-scrollview

我想让ScrollView从底部开始。有什么方法吗?

18 个答案:

答案 0 :(得分:308)

你应该在scroll.post中运行代码,如下所示:

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});

答案 1 :(得分:218)

scroll.fullScroll(View.FOCUS_DOWN)也应该有用。

答案 2 :(得分:56)

scroll.fullScroll(View.FOCUS_DOWN)将导致焦点转变。当有多个可聚焦视图时,这将带来一些奇怪的行为,例如两个EditText。这个问题有另一种方式。

    View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
    int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
    int sy = scrollLayout.getScrollY();
    int sh = scrollLayout.getHeight();
    int delta = bottom - (sy + sh);

    scrollLayout.smoothScrollBy(0, delta);

这很有效。

答案 3 :(得分:35)

最适合我的是

scroll_view.post(new Runnable() {
     @Override
     public void run() {
         // This method works but animates the scrolling 
         // which looks weird on first load
         // scroll_view.fullScroll(View.FOCUS_DOWN);

         // This method works even better because there are no animations.
         scroll_view.scrollTo(0, scroll_view.getBottom());
     }
});

答案 4 :(得分:34)

有时scrollView.post不起作用

 scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    });

但是如果你使用scrollView.postDelayed,肯定会有效

 scrollView.postDelayed(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    },1000);

答案 5 :(得分:28)

我增加了完美的工作。

    private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }

注意

这个答案是针对真正旧版Android的解决方法。今天postDelayed没有更多的bug,你应该使用它。

答案 6 :(得分:4)

我尝试成功了。

DB::table('lines')
    ->join('bets', 'lines.bet_id', '=', 'bet_id')
    ->select('lines.sport_id', 'bets.*')
    ->where('lines.sport_id',$sport_id)
    ->orderBy('bets.stake')
    ->get();

答案 7 :(得分:3)

当尚未加载视图时,您无法滚动。您可以通过上面的帖子或睡眠呼叫“稍后”进行,但这不是很优雅。

最好规划滚动并在下一个onLayout()上执行。示例代码:

https://stackoverflow.com/a/10209457/1310343

答案 8 :(得分:3)

要考虑的一件事是不要设置。确保您的子控件(尤其是EditText控件)没有设置RequestFocus属性。这可能是布局上最后解释的属性之一,它将覆盖其父级(布局或ScrollView)上的重力设置。

答案 9 :(得分:1)

不完全是问题的答案,但是我需要在EditText获得焦点后立即向下滚动。然而,接受的答案将使ET也立即失去焦点(我假设的ScrollView)。

我的解决方法如下:

emailEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus){
            Toast.makeText(getActivity(), "got the focus", Toast.LENGTH_LONG).show();
            scrollView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scrollView.fullScroll(ScrollView.FOCUS_DOWN);
                }
            }, 200);
        }else {
            Toast.makeText(getActivity(), "lost the focus", Toast.LENGTH_LONG).show();
        }
    }
});

答案 10 :(得分:1)

我实际上发现两次调用fullScroll可以达到目的:

myScrollView.fullScroll(View.FOCUS_DOWN);

myScrollView.post(new Runnable() {
    @Override
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

执行第一次(不成功)滚动之后,可能与激活post()方法有关。我认为在对myScrollView进行任何先前的方法调用之后都会发生此行为,因此您可以尝试用与您相关的任何其他方法替换第一个fullScroll()方法。

答案 11 :(得分:0)

所有答案的组合对我有用:

扩展函数 PostDelayed

private fun ScrollView.postDelayed(
    time: Long = 325, // ms
    block: ScrollView.() -> Unit
) {
    postDelayed({block()}, time)
}

扩展函数 measureScrollHeight

fun ScrollView.measureScrollHeight(): Int {
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY+ height)
    return delta
}

扩展功能ScrolltoBottom

fun ScrollView.scrollToBottom() {
    postDelayed {
        smoothScrollBy(0, measureScrollHeight())
    }
}

请注意,最小延迟应至少为 325 毫秒,否则滚动会出错(不会滚动到整个底部)。当前高度和底部之间的增量越大,延迟时间应该越大。

答案 12 :(得分:0)

如果您的最低 SDK 为 23 或更高版本,您可以使用:

View childView = findViewById(R.id.your_view_id_in_the_scroll_view)
if(childView != null){
  scrollview.post(() -> scrollview.scrollToDescendant(childView));
}

答案 13 :(得分:0)

立即有效。刻不容缓。

    private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs args)     
    {
        if (args.RightButton == MouseButtonState.Pressed)                
        {
            currentPoint = args.GetPosition(this);
        }
    }
    private void OnPreviewMouseRightButtonUp(object sender, MouseButtonEventArgs args)      
    {
        if (args.RightButton == MouseButtonState.Released)                  
        {      
            Line line = new Line();
            line.Stroke = SystemColors.WindowFrameBrush;
            line.X1 = currentPoint.X;
            line.Y1 = currentPoint.Y;
            line.X2 = currentPoint_2.X;
            line.Y2 = currentPoint_2.Y;
            line.StrokeThickness = 2;
            canvasOn3D.Children.Add(line);
         }
    }

答案 14 :(得分:0)

scroll.fullScroll(View.FOCUS_DOWN)甚至不能封装在.post()中也可能无法工作的一个可能原因是视图未布置。在这种情况下,View.doOnLayout()可能是更好的选择:

scroll.doOnLayout(){
    scroll.fullScroll(View.FOCUS_DOWN)
}

或者,为勇敢的灵魂精心制作的东西:https://chris.banes.dev/2019/12/03/suspending-views/

答案 15 :(得分:0)

还有其他一些滚动到底部的方法

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

使用

如果您已经滚动视图了

my_scroll_view.scrollToBottom()

如果滚动视图的布局尚未完成(例如:您在“活动onCreate方法中滚动到底部...”

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}

答案 16 :(得分:0)

在那种情况下,仅使用 scroll.scrollTo(0,sc.getBottom())不起作用,请使用 scroll.post

示例:

scroll.post(new Runnable() {
  @Override
  public void run() {
  scroll.fullScroll(View.FOCUS_DOWN);
  } 
});

答案 17 :(得分:0)

使用Kotlin协程可以使用另一种很酷的方法。使用与具有可运行(post / postDelayed)的Handler相对应的协程的优点是它不会启动昂贵的线程来执行延迟操作。

launch(UI){
    delay(300)
    scrollView.fullScroll(View.FOCUS_DOWN)
}

将协程的HandlerContext指定为UI非常重要,否则可能无法从UI线程调用延迟的操作。