我正在尝试设置水平滚动视图的位置,使其与按下的按钮相对应。我尝试用这个来设置它但不成功:
HorizontalScrollView hsv = (HorizontalScrollView)findViewById(R.id.ScrollView);
int x, y;
x = hsv.getLeft();
y = hsv.getTop();
hsv.scrollTo(x, y);
这不会产生任何结果,滚动视图不受影响。 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>
因此,如果在新活动开始时按下第五个按钮(位于屏幕外),我想设置新视图,以便水平滚动视图一直向右,而不是一直向左开始。
如何设置水平滚动视图的位置?
现在您正在尝试滚动到 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);
编辑:
如果将这段代码放在
onCreate()
中,其行为将不会如您所期望的那样。即使你已经调用了setContentView()
,布局还没有被测量和初始化。这意味着 getLeft()
和 getTop()
方法 都将返回 0。尝试在布局完全初始化之前设置滚动位置没有任何效果,因此您需要在 hsv.scrollTo()
之后一段时间调用 onCreate()
。
似乎有效的一个选项是将代码放入
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);
}
但是,每次 Activity 获得或失去焦点时都会调用此函数,因此您最终可能会比预期更频繁地更新滚动位置。
一个更优雅的解决方案是在知道视图已初始化后,对 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());
}
}
创建 MyHorizontalScrollView 时,它会自动膨胀并添加按钮布局。然后在调用超级
onMeasure()
(以便它知道布局已完成初始化)后,它设置滚动位置。
这是新的 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" />
这是由 MyHorizontalScrollView 自动膨胀的 Buttons.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>
虽然这是一个老问题,但我最近遇到了同样的问题,并找到了另一个但不太复杂的解决方案。
让我们假设原始问题中给定的布局文件,并假设如果一个活动以给定的布局启动,则水平滚动视图需要滚动到按钮 5。
要实现滚动到按钮 5,请将以下代码放入 Activity 的
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);
}
});
}
}