Android设置水平scrollview的位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10507976/
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
Android setting position of hortizontal scrollview
提问by Nick
I am trying to set the position of the horizontal scrollview so it corresponds with the button that is pushed. I've tried using this to set it unsuccessfully:
我正在尝试设置水平滚动视图的位置,使其与按下的按钮相对应。我试过用它来设置它不成功:
HorizontalScrollView hsv = (HorizontalScrollView)findViewById(R.id.ScrollView);
int x, y;
x = hsv.getLeft();
y = hsv.getTop();
hsv.scrollTo(x, y);
This results in nothing, the scrollview is unaffected. The xml:
这没有任何结果,滚动视图不受影响。xml:
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ScrollView"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="@null"
android:scrollbars="none" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn0"
android:id="@+id/btn0"
android:background="@drawable/yellow_btn" />
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:background="@drawable/yellow_btn"
android:text="bnt1"
android:id="@+id/btn1" />
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:background="@drawable/yellow_btn"
android:text="btn2"
android:id="@+id/btn2" />
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:background="@drawable/yellow_btn"
android:text="btn3"
android:id="@+id/btn3" />
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:background="@drawable/yellow_btn"
android:text="btn4"
android:id="@+id/btn4" />
<Button
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:background="@drawable/yellow_btn"
android:text="btn5"
android:id="@+id/btn5" />
</LinearLayout>
</HorizontalScrollView>
So if the 5th button is pushed (which is offscreen) when the new activity that starts I want to set the new view so the horizontal scrollview is all the way to the right versus starting out all the way to the left.
因此,如果在启动新活动时按下第 5 个按钮(屏幕外),我想设置新视图,以便水平滚动视图一直向右,而不是一直向左开始。
How can I set the position of the horizontal scrollview?
如何设置水平滚动视图的位置?
回答by theisenp
Right now you are trying to scroll to the top-left corner of the HorizontalScrollView rather than the position of the button. Try scrolling to the (x, y) position of the button like this:
现在您正在尝试滚动到 HorizontalScrollView 的左上角而不是按钮的位置。尝试滚动到按钮的 (x, y) 位置,如下所示:
HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView);
Button button = (Button) findViewById(R.id.btn5);
int x, y;
x = button.getLeft();
y = button.getTop();
hsv.scrollTo(x, y);
EDIT:
编辑:
This code will not behave as you would expect if it is placed in onCreate()
. Even though you have called setContentView()
, the layout has not been measured and initialized yet. This means that the getLeft()
and getTop()
methods will both return 0. Trying to set the scroll position before the layout is fully initialized has no effect, so you need to call hsv.scrollTo()
some time after onCreate()
.
如果将此代码放置在onCreate()
. 即使您调用了setContentView()
,布局还没有被测量和初始化。这意味着getLeft()
和getTop()
方法都将返回 0。尝试在布局完全初始化之前设置滚动位置无效,因此您需要hsv.scrollTo()
在onCreate()
.
One option that seems to work is placing the code in onWindowFocusChanged()
:
似乎可行的一种选择是将代码放在onWindowFocusChanged()
:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView);
Button button = (Button) findViewById(R.id.btn5);
int x, y;
x = button.getLeft();
y = button.getTop();
hsv.scrollTo(x, y);
}
However, this function is called every time the Activity gains or loses focus, so you might end up updating the scroll position more often than you intended.
但是,每次 Activity 获得或失去焦点时都会调用此函数,因此您最终可能会比预期更频繁地更新滚动位置。
A more elegant solution would be to subclass the HorizontalScrollView and set the scroll position in onMeasure()
, after you know that the view has been initialized. To do this, I split your layout into two files and added a new class named MyHorizontalScrollView:
一个更优雅的解决方案是将 HorizontalScrollView 子类化并onMeasure()
在您知道视图已初始化后设置滚动位置。为此,我将您的布局拆分为两个文件,并添加了一个名为 MyHorizontalScrollView 的新类:
package com.theisenp.test;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.HorizontalScrollView;
public class MyHorizontalScrollView extends HorizontalScrollView {
public MyHorizontalScrollView(Context context) {
super(context);
addButtons(context);
}
public MyHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
addButtons(context);
}
/**
* Inflates the layout containing the buttons and adds them to the ScrollView
* @param context
*/
private void addButtons(Context context) {
View buttons = inflate(context, R.layout.buttons, null);
addView(buttons);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//Find button 5 and scroll to its location
View button = findViewById(R.id.btn5);
scrollTo(button.getLeft(), button.getTop());
}
}
When MyHorizontalScrollView is created, it automatically inflates and adds the button layout. Then after calling the super onMeasure()
(so that it knows the layout has finished initializing) it sets the scroll position.
创建 MyHorizontalScrollView 时,它会自动膨胀并添加按钮布局。然后在调用 super 之后onMeasure()
(以便它知道布局已完成初始化),它设置滚动位置。
This is the new main.xml. It only contains the new MyHorizontalScrollView, though you could easily put it inside of a Linear or Relative layout and add other view elements. (You would replace com.theisenp.test
with the name of the package where MyHorizontalScrollView is located):
这是新的 main.xml。它只包含新的 MyHorizontalScrollView,但您可以轻松地将它放在线性或相对布局中并添加其他视图元素。(您将替换com.theisenp.test
为 MyHorizontalScrollView 所在的包的名称):
<?xml version="1.0" encoding="utf-8"?>
<com.theisenp.test.MyHorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ScrollView"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="@null"
android:scrollbars="none" />
And this is the buttons.xml layout that is automatically inflated by MyHorizontalScrollView:
这是由 MyHorizontalScrollView 自动膨胀的 button.xml 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/btn0"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn0" />
<Button
android:id="@+id/btn1"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="bnt1" />
<Button
android:id="@+id/btn2"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn2" />
<Button
android:id="@+id/btn3"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn3" />
<Button
android:id="@+id/btn4"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn4" />
<Button
android:id="@+id/btn5"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_marginBottom="-5dp"
android:text="btn5" />
</LinearLayout>
回答by Tomasz Nguyen
Although, this is an old question, I recently run into the same problem and found yet another but rather less complex solution.
虽然这是一个老问题,但我最近遇到了同样的问题,并找到了另一个但不太复杂的解决方案。
Let's assume the given layout file in the original question and let's assume that if an activity is started with the given layout, the horizontal scrollview needs to be scrolled to button 5.
让我们假设原始问题中的给定布局文件,并假设如果活动以给定布局开始,则水平滚动视图需要滚动到按钮 5。
To achieve scrolling to button 5, put the following code in the onCreate()
method of the activity:
要实现滚动到按钮 5,请将以下代码放入onCreate()
活动的方法中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Some code such as layout inflation.
final HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView);
// Scrolling to button 5.
hsv.post(new Runnable() {
@Override
public void run() {
// Get the button.
View button = findViewById(R.id.btn5);
// Locate the button.
int x, y;
x = button.getLeft();
y = button.getTop();
// Scroll to the button.
hsv.scrollTo(x, y);
}
});
}
}