如何滚动到长 ScrollView 布局的顶部?
Posted
技术标签:
【中文标题】如何滚动到长 ScrollView 布局的顶部?【英文标题】:How to scroll to top of long ScrollView layout? 【发布时间】:2011-05-06 09:19:17 【问题描述】:对于我的应用程序的一部分,用户会看到一个名称列表,并要求用户按照他们认为合适的方式对它们进行分组。
(注意,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 中包含的屏幕上加载一堆视图,然后以编程方式将整个内容滚动到页面顶部,以便用户可以与之交互?
谢谢!
【问题讨论】:
【参考方案1】:我在 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()
【讨论】:
【参考方案2】:此解决方案也适用于 NestedScrollView
NestedScrollView nestedScrollView = view.findViewById(R.id.YourNestedScrollViewID);
nestedScrollView.fullScroll(ScrollView.FOCUS_UP);
【讨论】:
【参考方案3】: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);
);
【讨论】:
我正在处理滚动视图应该滚动到页面底部的相同问题,将其修复! View 对象提供了一个 post(Runnable) 方法,您可以使用该方法,而不是猜测“神奇”x 您必须等待的毫秒数,该方法将在小部件在 UI 上呈现后发布可运行对象. @Ryan : post(Runnable) 在 Nexus 5 (Genymotion) 上对我总是不起作用 post(Runnable) 可能不起作用,因为如果您在视图膨胀步骤之后获取数据,则首先向上滚动工作,然后数据填充到视图中。所以你要么你应该使用 postDelayed(Runnable,dummyMillis) 要么你应该在数据填充过程之后使用 scroll.fullScroll(ScrollView.FOCUS_UP)。 您提供静态毫秒的第一个解决方案是一种糟糕的方法。【参考方案4】:这对我有用
scroll_view.smoothScrollTo(0,0); // scroll to top of screen
【讨论】:
【参考方案5】:scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
// Ready, move up
scrollView.fullScroll(View.FOCUS_UP);
);
【讨论】:
【参考方案6】:这是 scrollview 的强制滚动:
scrollView.post(new Runnable()
@Override
public void run()
scrollView.scrollTo(0, 0);
scrollView.pageScroll(View.FOCUS_UP);
scrollView.smoothScrollTo(0,0);
);
【讨论】:
【参考方案7】:@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);
【讨论】:
这肯定会运行, 请简要说明此答案如何解决问题。【参考方案8】:很简单
ScrollView scroll = (ScrollView) findViewById(R.id.addresses_scroll);
scroll.setFocusableInTouchMode(true);
scroll.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
【讨论】:
对我来说它不起作用(第 3 行),解决方案是:scroll.fullScroll(View.FOCUS_UP); (包括你的前 2 行) @medskill,嗨,你把这些写在你的 xml 文件中了吗?我发现这只适用于onCreate()
。
@imknownJ.Kimu 在 xml 文件中为我工作
这对我有用。您需要第二行和第三行。它不适用于我的 XML。
如果可以,我会吻你!在这上面花了 1-2 个小时。等待两个列表视图加载并且不想专注于它们时最好的一个。将其添加到 onResume() 中。【参考方案9】:
我有同样的问题,这解决了它。希望对你有帮助。
listView.setFocusable(false);
【讨论】:
这也是 gridviews 的正确解决方案。当您在同一视图组中有多个视图元素时会发生这种情况,尤其是列表或网格视图顶部的另一个列表视图。由于适配器通知 UI 线程,视图被重新创建并向上滚动到第一个元素。只需调用 listView.setFocusable(false) / gridView.setFocusable(false)。如果您从 xml 文件中执行此操作,则将无法正常工作。 这个解决方案也适用于我的情况,我在 NestedScrollView 中有 RecyclerView,所以它会自动向下滚动。谢谢,伙计! 我必须在设置适配器之前添加它,但之后就像一个魅力。谢谢 完美解释!! 感谢 Miguel 和特别是 omersem 的解释,特别是关于如果在 XML 中设置它将如何工作的部分,这让我有些头疼【参考方案10】: final ScrollView scrollview = (ScrollView)findViewById(R.id.selected_place_layout_scrollview);
scrollview.post(new Runnable()
public void run()
scrollview.scrollTo(0, 0);
);
【讨论】:
【参考方案11】:runOnUiThread( new Runnable()
@Override
public void run()
mainScrollView.fullScroll(ScrollView.FOCUS_UP);
【讨论】:
【参考方案12】:试试
mainScrollView.fullScroll(ScrollView.FOCUS_UP);
它应该可以工作。
【讨论】:
也适合我。 :D 我发现 ScrollView#fullScroll() 改变了当前焦点。我用 EditText 测试过。【参考方案13】:所有这些有效解决方案的主要问题是,当滚动条尚未绘制在屏幕上时,您正试图向上移动它。
您需要等到滚动视图出现在屏幕上,然后使用任何这些解决方案将其向上移动。这是比后延迟更好的解决方案,因为您不介意延迟。
// Wait until my scrollView is ready
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
// Ready, move up
scrollView.fullScroll(View.FOCUS_UP);
);
【讨论】:
不错的解决方案 - 不要忘记在onGlobalLayout
方法调用 scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
结束时删除全局侦听器【参考方案14】:
当我在 View Flipper 或 Dialog 中使用 Scrollview 时,我遇到了同样的问题 scrollViewObject.fullScroll(ScrollView.FOCUS_UP)
返回 false ,因此 scrollViewObject.smoothScrollTo(0, 0)
对我有用
Scroll Focus Top
【讨论】:
【参考方案15】:有同样的问题,可能是某种错误。
即使来自其他答案的fullScroll(ScrollView.FOCUS_UP)
也不起作用。
唯一对我有用的是在显示对话框后立即调用scroll_view.smoothScrollTo(0,0)
。
【讨论】:
这最初是可行的,但后来当我一次又一次地尝试这样做时,这种方法并没有给出令人满意的结果。 我从 scroll_view.smoothScrollTo(0,0) 解决,当我们在滚动视图旁边有 listview 时 fullScroll(ScrollView.FOCUS_UP) 将不起作用。 scroll_view.smoothScrollTo(0,0) 对我来说比 mainScrollView.fullScroll(ScrollView.FOCUS_UP);谢谢! 在大多数设备上 fullScroll(ScrollView.FOCUS_UP) 工作,但在 Nexus 5 和我的文本大小调高的设备上 - fullSscroll 在操作栏下移动,smoothScrollTo(0,0) 工作在所有设备上都更好。 这也比fullScroll()
具有优势,因为它在移动后保持所选项目仍然处于选中状态。使用fullScroll()
,在我的情况下,每次都会重新选择滚动视图中的第一项,与滚动向上移动之前的选定项目无关。以上是关于如何滚动到长 ScrollView 布局的顶部?的主要内容,如果未能解决你的问题,请参考以下文章
在自动布局的情况下,IOS scrollview 模糊的可滚动内容高度
使 UIScrollView 中的顶部图像在滚动视图边界上放大?
android 自定义scrollview 仿QQ空间效果 下拉伸缩顶部图片,上拉回弹 上拉滚动顶部title 颜色渐变