171

对于我的应用程序的一部分,用户会看到一个名称列表,并被要求按照他们认为合适的方式对它们进行分组。

(注意,ListView 代码是从 Android 视图教程中逐字复制的。我还没有根据我的需要对其进行定制,我只是想弄清楚如何使它工作。)

基本布局是一个LinearLayout,包含一个ScrollView(在下面的代码中称为“groupsScrollView”),包含一个RelativeLayout。我有一些按钮和文本,然后是下面的 ListView,它显示名称列表。所有这些都高于可见屏幕区域,因此允许用户垂直滚动以查看所有内容。

这一切都很好,除了页面加载时它总是预先滚动到我的 ListView 的顶部 - 在页面的中间。我创建的告诉用户该做什么的文本和按钮是不可见的。

我可以抓住屏幕并向上滚动,效果很好,但我希望屏幕加载已经滚动到顶部。用户不必向上滚动即可看到新加载页面的顶部。但是我试图以编程方式滚动到屏幕顶部的一切都失败了。

这是我的 onCreate 方法:

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.groups);

    mainScrollView = (ScrollView)findViewById(R.id.groupsScrollView);

    //get the Bundle out of the Intent...
    Bundle extras = getIntent().getExtras();
    mNames = extras.getStringArray("mNames");

    setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, mNames));

    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    //This is the line I'm having issues with
    mainScrollView.pageScroll(View.FOCUS_UP);

    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
          // When clicked, show a toast with the TextView text
          Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
              Toast.LENGTH_SHORT).show();
        }
      });
}

“mainScrollView.pageScroll(View.FOCUS_UP); 行是问题。它不会导致错误,但它似乎没有做任何事情。我试过 scrollTo(0,0), scrollDirection(View.FOCUS_UP ),以及我能想到的一切。

由于我没有收到错误,我必须假设这些滚动命令实际上正在工作,但它们正在滚动到 ListView 的顶部,而不是滚动到包含它的 ScrollView 或 RelativeLayout 的顶部。谷歌自己对 scrollTo(int x, int y) 方法的描述似乎证实了这一点,他们说“这个版本还将滚动限制在我们孩子的范围内。”。

因此,为了让一个更长的问题变得更长,我如何在 ScrollView 中包含的屏幕上加载一堆视图,然后以编程方式将整个内容滚动到页面顶部,以便用户可以与之交互?

谢谢!

4

15 回答 15

283

尝试

mainScrollView.fullScroll(ScrollView.FOCUS_UP);

它应该工作。

于 2011-01-23T13:15:46.297 回答
180

有同样的问题,可能是某种错误。

即使fullScroll(ScrollView.FOCUS_UP)来自另一个答案也不起作用。
唯一对我有用scroll_view.smoothScrollTo(0,0)的是在显示对话框后立即调用。

于 2012-05-19T20:10:00.270 回答
100

我有同样的问题,这解决了它。希望它可以帮助你。

listView.setFocusable(false);
于 2014-07-11T18:12:16.423 回答
58

scrollViewObject.fullScroll(ScrollView.FOCUS_UP)这工作正常,但只有这一行的问题是,当数据填充到 scrollViewObject 时,已立即调用。您必须等待几毫秒才能填充数据。试试这个代码:

scrollViewObject.postDelayed(new Runnable() {
    @Override
    public void run() {
        scroll.fullScroll(ScrollView.FOCUS_UP);
    }
}, 600);

或者

 scrollViewObject.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        scrollViewObject.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        scrollViewObject.fullScroll(View.FOCUS_UP);
    }
});
于 2013-05-17T06:21:21.183 回答
36

所有这些有效解决方案的主要问题是,当滚动条尚未在屏幕上绘制时,您正试图向上移动它。

您需要等到滚动视图出现在屏幕上,然后使用这些解决方案中的任何一个将其向上移动。这是比后延迟更好的解决方案,因为您不介意延迟。

    // Wait until my scrollView is ready
    scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            // Ready, move up
            scrollView.fullScroll(View.FOCUS_UP);
        }
    });
于 2013-10-30T08:35:27.473 回答
30

很容易

    ScrollView scroll = (ScrollView) findViewById(R.id.addresses_scroll);
    scroll.setFocusableInTouchMode(true);
    scroll.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
于 2016-01-28T20:42:49.837 回答
25

当我在 View Flipper 或 Dialog 中使用 Scrollview 时,我遇到了同样的问题,该案例 scrollViewObject.fullScroll(ScrollView.FOCUS_UP)返回 false,因此该案例 scrollViewObject.smoothScrollTo(0, 0)适用于我

滚动焦点顶部

于 2012-12-12T09:56:22.953 回答
20
 final ScrollView scrollview = (ScrollView)findViewById(R.id.selected_place_layout_scrollview);

         scrollview.post(new Runnable() { 
                public void run() { 
                    scrollview.scrollTo(0, 0); 
                } 
            }); 
于 2014-07-02T06:56:06.397 回答
12

这对我有用

scroll_view.smoothScrollTo(0,0); // scroll to top of screen
于 2018-03-21T09:02:45.167 回答
9
runOnUiThread( new Runnable(){
   @Override
   public void run(){
      mainScrollView.fullScroll(ScrollView.FOCUS_UP);
   }
}
于 2014-02-26T12:46:51.103 回答
8

我像这样在 Kotlin 中解决了我的问题:

scrollview.isFocusableInTouchMode = true
scrollview.fullScroll(View.FOCUS_UP)
scrollview.smoothScrollTo(0,0)

您还可以创建这样的扩展:

ScrollView.moveToTop()
{
    this.isFocusableInTouchMode = true
    this.fullScroll(View.FOCUS_UP)
    this.smoothScrollTo(0,0)
}

并像这样使用它:

scrollView.moveToTop()
于 2020-02-13T09:10:49.520 回答
6

这是scrollview的强制滚动:

            scrollView.post(new Runnable() {
                @Override
                public void run() {
                    scrollView.scrollTo(0, 0);
                    scrollView.pageScroll(View.FOCUS_UP);
                    scrollView.smoothScrollTo(0,0);
                }
            });
于 2017-09-19T06:37:51.213 回答
4
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Ready, move up
        scrollView.fullScroll(View.FOCUS_UP);
    }
});
于 2018-01-27T17:19:09.163 回答
1

此解决方案也适用于 NestedScrollView

NestedScrollView nestedScrollView = view.findViewById(R.id.YourNestedScrollViewID);
nestedScrollView.fullScroll(ScrollView.FOCUS_UP);
于 2020-08-22T08:34:16.730 回答
0
@SuppressWarnings({ "deprecation", "unchecked" })
public void swipeTopToBottom(AppiumDriver<MobileElement> driver) 
                    throws InterruptedException {
       Dimension dimensions = driver.manage().window().getSize();
        Double screenHeightStart = dimensions.getHeight() * 0.30;
        int scrollStart = screenHeightStart.intValue();
        System.out.println("s="+scrollStart);
        Double screenHeightEnd = dimensions.getHeight()*0.90;
        int scrollEnd = screenHeightEnd.intValue();
        driver.swipe(0,scrollStart,0,scrollEnd,2000);
        CommonUtils.threadWait(driver, 3000);
    }
于 2017-07-18T12:11:09.273 回答