【问题标题】:Can I scroll a ScrollView programmatically in Android?我可以在 Android 中以编程方式滚动 ScrollView 吗?
【发布时间】:2011-09-20 06:01:59
【问题描述】:

有没有办法以编程方式将ScrollView 滚动到某个位置?

我创建了动态TableLayout,它被放置在ScrollView 中。因此,我希望在特定操作(例如单击按钮等)上,特定行应自动滚动到顶部位置。

有可能吗?

【问题讨论】:

    标签: java android scrollview android-scrollview


    【解决方案1】:

    Pragna 的答案并不总是有效,试试这个:

    mScrollView.post(new Runnable() { 
            public void run() { 
                 mScrollView.scrollTo(0, mScrollView.getBottom());
            } 
    });
    

    mScrollView.post(new Runnable() { 
            public void run() { 
                 mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
            } 
    });
    

    如果你想滚动开始

    mScrollView.post(new Runnable() { 
            public void run() { 
                 mScrollView.fullScroll(mScrollView.FOCUS_UP);
            } 
    });
    

    【讨论】:

    • 我成功使用了mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
    • 我可以确认 Vanthel 的发现。可运行的帖子中的 mScrollView.fullScroll 起到了作用。
    • 太棒了!事实上,没有 Runnable,它就行不通。现在,它起作用了! :)
    • @HiteshDhamshaniya 如果你想要流畅的滚动,试试mScrollView.smoothScrollTo(0, mScrollView.getBottom());
    • 这里为什么需要post
    【解决方案2】:
    ScrollView sv = (ScrollView)findViewById(R.id.scrl);
    sv.scrollTo(0, sv.getBottom());
    

    sv.scrollTo(5, 10);

    【讨论】:

    • 结合ercu的回答和评论,最好的办法似乎是:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
    • scrollTo() 不会产生期望结果。应该使用 fullScroll()
    • 更漂亮的滚动效果更自然:sv.smoothScrollTo(5, 10)
    【解决方案3】:

    我希望 scrollView 在 onCreateView() 之后直接滚动(而不是在单击按钮之后)。为了让它工作,我需要使用 ViewTreeObserver:

    mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mScrollView.post(new Runnable() {
                    public void run() {
                        mScrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        });
    

    但请注意,每次布局时都会调用它(例如,如果您将视图设置为不可见或类似的),因此如果您不再需要此侦听器,请不要忘记删除它:

    public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) 在 SDK Lvl

    public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) 在 SDK Lvl >= 16

    【讨论】:

      【解决方案4】:

      这里有很多好的答案,但我只想补充一件事。有时您希望将 ScrollView 滚动到布局的特定视图,而不是完全滚动到顶部或底部。

      一个简单的例子:在注册表单中,如果用户在未填写表单的编辑文本时点击“注册”按钮,您希望滚动到特定的编辑文本以告诉用户他必须填写字段。

      在这种情况下,您可以这样做:

      scrollView.post(new Runnable() { 
              public void run() { 
                   scrollView.scrollTo(0, editText.getBottom());
              } 
      });
      

      或者,如果您想要平滑滚动而不是即时滚动:

      scrollView.post(new Runnable() { 
                  public void run() { 
                       scrollView.smoothScrollTo(0, editText.getBottom());
                  } 
          });
      

      显然,您可以使用任何类型的视图来代替编辑文本。请注意,getBottom() 根据其父布局返回视图的坐标,因此 ScrollView 内使用的所有视图都应该只有一个父视图(例如线性布局)。

      如果 ScrollView 的子级中有多个父级,我发现的唯一解决方案是在父级视图上调用 requestChildFocus:

      editText.getParent().requestChildFocus(editText, editText);
      

      但在这种情况下,您无法平滑滚动。

      我希望这个答案可以帮助有同样问题的人。

      【讨论】:

      • @JohnT 很高兴它帮助了你:)
      【解决方案5】:

      使用这样的东西:

      mScrollView.scrollBy(10, 10);
      

      mScrollView.scrollTo(10, 10);
      

      【讨论】:

        【解决方案6】:

        尝试使用scrollTo方法More Info

        【讨论】:

          【解决方案7】:

          如果你想立即滚动,那么你可以使用:

          ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
          scroll.scrollTo(0, scroll.getBottom());
          
                      OR
          
          scroll.fullScroll(View.FOCUS_DOWN);
          
                      OR
          
          scroll.post(new Runnable() {            
              @Override
              public void run() {
                     scroll.fullScroll(View.FOCUS_DOWN);              
              }
          });
          

          或者,如果您想平稳缓慢地滚动,您可以使用这个:

          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();
              }
          

          【讨论】:

          • catch 块有什么作用?
          • Catch 块用于在滚动过程中捕获异常(如果发现)。
          【解决方案8】:

          **向上滚动到所需的高度。我想出了一些好的解决方案**

                          scrollView.postDelayed(new Runnable() {
                              @Override
                              public void run() {
                                  scrollView.scrollBy(0, childView.getHeight());
                              }
                          }, 100);
          

          【讨论】:

            【解决方案9】:

            是的,你可以。

            假设你有一个Layout,而在其中,你有很多Views。所以如果你想以编程方式滚动到任何View,你必须编写以下代码sn-p:

            例如:

            content_main.xml

            <ScrollView
                android:id="@+id/scrollView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
            
                    <Button
                        android:id="@+id/btn"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
            
                    <TextView
                        android:id="@+id/txtView"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
            
                </LinearLayout>
            </ScrollView>
            

            MainActivity.java

            ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
            Button btn = (Button) findViewById(R.id.ivEventBanner);
            TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);
            

            如果你想滚动到特定的View,比如说txtview,在这种情况下,只需写:

            scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());
            

            你就完成了。

            【讨论】:

              【解决方案10】:

              我让它滚动到 ScrollView 的底部(里面有一个 TextView):

              (我把它放在一个更新 TextView 的方法上)

              final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
                  myScrollView.post(new Runnable() {
                  public void run() {
                      myScrollView.fullScroll(View.FOCUS_DOWN);
                  }
              });
              

              【讨论】:

                【解决方案11】:

                注意:如果您已经在一个线程中,您必须创建一个新的帖子线程,否则它不会滚动新的长高度直到完全结束(对我而言)。 例如:

                void LogMe(final String s){
                    runOnUiThread(new Runnable() {
                        public void run() {
                            connectionLog.setText(connectionLog.getText() + "\n" + s);
                            final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
                            sv.post(new Runnable() {
                                public void run() {
                                    sv.fullScroll(sv.FOCUS_DOWN);
                                    /*
                                    sv.scrollTo(0,sv.getBottom());
                                    sv.scrollBy(0,sv.getHeight());*/
                                }
                            });
                        }
                    });
                }
                

                【讨论】:

                  【解决方案12】:

                  添加另一个不涉及坐标的答案。

                  这将使您想要的视图成为焦点(但不是顶部位置):

                    yourView.getParent().requestChildFocus(yourView,yourView);
                  

                  public void RequestChildFocus(查看孩子,查看重点)

                  child - 这个 ViewParent 想要获得焦点的孩子。此视图将包含焦点视图。它不一定是真正具有焦点的视图。

                  focused - 实际上具有焦点的 child 的后代视图

                  【讨论】:

                  • 正是我需要的,谢谢。首先为您滚动视图请求焦点,然后 scrollView.smoothScrollTo(0, scrollView.getChildAt(0).getBottom());
                  【解决方案13】:

                  只是页面滚动:

                  ScrollView sv = (ScrollView) findViewById(your_scroll_view);
                  sv.pageScroll(View.FOCUS_DOWN);
                  

                  【讨论】:

                    【解决方案14】:

                    每个人都在发布如此复杂的答案。

                    我找到了一个简单的答案,很好地滚动到底部:

                    final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);
                    
                    // Scroll views can only have 1 child, so get the first child's bottom,
                    // which should be the full size of the whole content inside the ScrollView
                    myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
                    

                    并且,如果需要,您可以将上面的第二行代码放入可运行文件中:

                    myScroller.post( new Runnable() {
                        @Override
                        public void run() {
                            myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
                        }
                    }
                    

                    我花了很多时间研究并四处寻找这个简单的解决方案。我也希望它对你有帮助! :)

                    【讨论】:

                      【解决方案15】:

                      我使用 Runnable 和 sv.fullScroll(View.FOCUS_DOWN); 它非常适合当前的问题,但是该方法使 ScrollView 从整个屏幕中获取焦点,如果您每次都使 AutoScroll 发生,则没有 EditText 将能够从用户那里接收信息,我的解决方案是使用不同的代码在runnable下:

                      sv.scrollTo(0, sv.getBottom() + sv.getScrollY());

                      在不失去对重要观点的关注的情况下做同样的事情

                      问候。

                      【讨论】:

                        【解决方案16】:

                        它对我有用

                        mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                                @Override
                                public void onGlobalLayout() {
                                    mScrollView.post(new Runnable() {
                                        public void run() {
                                            mScrollView.fullScroll(View.FOCUS_DOWN);
                                        }
                                    });
                                }
                            });
                        

                        【讨论】:

                          【解决方案17】:
                          private int totalHeight = 0;
                          
                          ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
                          ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                              @Override
                              public void onGlobalLayout() {
                                  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                                      loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                                  } else {
                                      loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                                  }
                                  TotalHeight = loutMain.getMeasuredHeight();
                          
                              }
                          });
                          
                          scrollMain.smoothScrollTo(0, totalHeight);
                          

                          【讨论】:

                            【解决方案18】:
                            I had to create Interface
                            
                            public interface ScrollViewListener {
                                void onScrollChanged(ScrollViewExt scrollView, 
                                                     int x, int y, int oldx, int oldy);
                            }    
                            
                            import android.content.Context;
                            import android.util.AttributeSet;
                            import android.widget.ScrollView;
                            
                            public class CustomScrollView extends ScrollView {
                                private ScrollViewListener scrollViewListener = null;
                                public ScrollViewExt(Context context) {
                                    super(context);
                                }
                            
                                public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
                                    super(context, attrs, defStyle);
                                }
                            
                                public CustomScrollView (Context context, AttributeSet attrs) {
                                    super(context, attrs);
                                }
                            
                                public void setScrollViewListener(ScrollViewListener scrollViewListener) {
                                    this.scrollViewListener = scrollViewListener;
                                }
                            
                                @Override
                                protected void onScrollChanged(int l, int t, int oldl, int oldt) {
                                    super.onScrollChanged(l, t, oldl, oldt);
                                    if (scrollViewListener != null) {
                                        scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
                                    }
                                }
                            }
                            
                            
                            
                            
                            <"Your Package name ".CustomScrollView 
                                xmlns:android="http://schemas.android.com/apk/res/android"
                                xmlns:app="http://schemas.android.com/apk/res-auto"
                                android:id="@+id/scrollView"
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"
                                android:focusableInTouchMode="true"
                                android:scrollbars="vertical">
                            
                                private CustomScrollView scrollView;
                            
                            scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
                                    scrollView.setScrollViewListener(this);
                            
                            
                                @Override
                                public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
                                    // We take the last son in the scrollview
                                    View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
                                    int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));
                            
                                    // if diff is zero, then the bottom has been reached
                                    if (diff == 0) {
                                            // do stuff
                                        //TODO keshav gers
                                        pausePlayer();
                                        videoFullScreenPlayer.setVisibility(View.GONE);
                            
                                    }
                                }
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-02-13
                              • 1970-01-01
                              • 2013-11-15
                              • 2015-11-14
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多