水平スクロールビューの位置を、押したボタンに対応するように設定しようとしています。これを使用して失敗に設定しようとしました:
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>
したがって、開始する新しいアクティビティのときに5番目のボタン(画面外)が押された場合、新しいビューを設定して、水平スクロールビューが右端になり、左端から開始するようにします。
水平スクロールビューの位置を設定するにはどうすればよいですか?
現在、ボタンの位置ではなく、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()
を呼び出す必要があります。
機能しているように見える1つのオプションは、コードを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);
}
_
ただし、この関数はアクティビティがフォーカスを取得または失うたびに呼び出されるため、意図したよりも頻繁にスクロール位置を更新してしまう可能性があります。
よりエレガントな解決策は、HorizontalScrollViewをサブクラス化し、ビューが初期化されたことがわかった後、onMeasure()
にスクロール位置を設定することです。これを行うために、レイアウトを2つのファイルに分割し、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が作成されると、ボタンレイアウトが自動的に拡張および追加されます。次に、super 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までスクロールするには、アクティビティの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);
}
});
}
}