Java 以编程方式将 ScrollView 聚焦到选定位置 - Android

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18188201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:08:09  来源:igfitidea点击:

Focus ScrollView to selected position programmatically - Android

javaandroidscrollview

提问by Matt

I have a ScrollView with a lot buttons. Each button is enabled when the user unlocks that button/level. I would like to focus the ScrollView on the latest unlocked button/level. See the screenshot below.

我有一个带有很多按钮的 ScrollView。当用户解锁该按钮/级别时,将启用每个按钮。我想将 ScrollView 集中在最新的解锁按钮/级别上。请参阅下面的屏幕截图。

enter image description here

在此处输入图片说明

I found some functions like scrollTo()that could focus the ScrollView either at top, button or something like that but I would like to focus the ScrollView at certain places like the button ID that says Level 8in the screenshot below. How would I go about doing this?

我发现一些类似的功能scrollTo()可以将 ScrollView 聚焦在顶部、按钮或类似的地方,但我想将 ScrollView 聚焦在某些位置,例如Level 8下面屏幕截图中显示的按钮 ID 。我该怎么做呢?

回答by alvi

see: http://developer.android.com/reference/android/widget/ListView.html#setSelectionFromTop(int, int)

见:http: //developer.android.com/reference/android/widget/ListView.html#setSelectionFromTop(int , int)

  • 'int selectedLevel' holds the currently selected level, information is held in a Levelclass.
  • 'values' is a list with all your levels, displayed by the list.
  • 'int selectedLevel' 保存当前选择的级别,信息保存在一个Level类中。
  • 'values' 是一个包含所有级别的列表,由列表显示。

Example:

例子:

    ListView lv = (ListView)findViewById(android.R.id.list);
    int i = 0;
    for (Level l : values) {
        i++;
        if (l.level == selectedLevel) {
            lv.setSelectionFromTop(i, 200);
            break;
        }
    }

回答by Sourabh Saldi

First you need to know the position of item in scroll that has to get focus once you know that you can use following code to make that item focus

首先,您需要知道滚动中项目的位置,一旦您知道可以使用以下代码使该项目成为焦点,就必须获得焦点

    final int x;
            final int y;
            x = rowview[pos].getLeft();
            y = rowView[pos].getTop();

                yourScrollView.scrollTo(x, y);

refer this question

参考这个问题

回答by Lmickos

I agree with the benefits of previous answers. However, by experience, I have found this to be more complex than this. The setSelectionFromTop is very sensitive and often breaks if it is executed too early. This may depend on different reasons but the two primary reasons are that

我同意以前答案的好处。但是,根据经验,我发现这比这更复杂。setSelectionFromTop 非常敏感,如果过早执行,通常会中断。这可能取决于不同的原因,但两个主要原因是

  • If executed from within Activity lifecycle methods the views have not been loaded/configured yet.
  • View modifications triggered after the list move action seems to break the move. Probably overwriting some value before the move has been finalized due to a recalculation of the views.
  • 如果在 Activity 生命周期方法中执行,则视图尚未加载/配置。
  • 列表移动操作似乎中断移动后触发的视图修改。由于重新计算视图,可能会在移动完成之前覆盖一些值。

The reasoning seems to apply for both setSelectionFromTop and setSelection() methods although I tested mostly with setSelectionFromTop. smoothScrollToPosition() seems to be more robust, probably because it by definition changes the list position delayed whn doing the smooth scrolling.

推理似乎适用于 setSelectionFromTop 和 setSelection() 方法,尽管我主要使用 setSelectionFromTop 进行了测试。smoothScrollToPosition() 似乎更健壮,可能是因为它根据定义更改了平滑滚动时延迟的列表位置。

Look at this example source code:

看看这个示例源代码:

// Wee need to pospone the list move until all other view setup activities are finished
list.post(new Runnable(){
    @override
    public void run() {
        list.setSelectionFromTop(selectedPosition, Math.max(0, Math.round(list.getHeight() / 3))); // Make sure selection is in middle of page, if possible.
        // Make sure you do not modify (this or other) parts of the view afterwards - it may break the list move
        // activityButtons.setVisibility(View.GONE);
}});

回答by Fahriyal Afif

try this

尝试这个

sc.post(new Runnable() { 
        public void run() { 
             sc.smoothScrollTo(x, y);
        } 
    });

x the position where to scroll on the X axis

x 在 X 轴上滚动的位置

y the position where to scroll on the Y axis

y 在 Y 轴上滚动的位置

回答by Swas_99

I think this should be good enough :

我认为这应该足够了:

  yourButtonView.getParent().requestChildFocus(yourButtonView,yourButtonView);

public void RequestChildFocus (View child, View focused)

public void RequestChildFocus(查看子项,查看焦点)

child- The child of this ViewParent that wants focus. This view will contain the focused view. It is not necessarily the view that actually has focus.

child- 想要获得焦点的这个 ViewParent 的孩子。该视图将包含聚焦视图。实际具有焦点的不一定是视图。

focused- The view that is a descendant of child that actually has focus

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

回答by TapanHP

Use this code, taken from this answer

使用此代码,取自此答案

private final void focusOnView(){
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                your_scrollview.scrollTo(0, your_EditBox.getBottom());
            }
        });
    }

回答by Suphi ?EV?KER

Use this code, taken from my another answer

使用此代码,取自我的另一个答案

scrollViewSignup.post(new Runnable() {
    @Override
    public void run() {
        int scrollY = scrollViewSignup.getScrollY();
        scrollViewSignup.scrollTo(0, 0);
        final Rect rect = new Rect(0, 0, view.getWidth(), view.getHeight());
        view.requestRectangleOnScreen(rect, true);

        int new_scrollY = scrollViewSignup.getScrollY();
        scrollViewSignup.scrollTo(0, scrollY);
        scrollViewSignup.smoothScrollTo(0, new_scrollY);
    }
});

This code tries to smooth scroll and uses the standard behaviour of system to position to an item. You can simply change smoothScrollTowith scrollTo if you don't want the system to smooth scroll to the item. Or, you can use the code below only.

此代码尝试平滑滚动并使用系统的标准行为来定位项目。如果您不希望系统平滑滚动到项目,您可以简单地使用 scrollTo更改smoothScrollTo。或者,您只能使用下面的代码。

scrollViewSignup.post(new Runnable() {
    @Override
    public void run() {
        scrollViewSignup.scrollTo(0, 0);
        final Rect rect = new Rect(0, 0, view.getWidth(), view.getHeight());
        view.requestRectangleOnScreen(rect, true);
    }
});

Use the desired code block after trying, or, according to the need.

尝试后使用所需的代码块,或者根据需要使用。