Положение установки Android для горизонтального прокрутки

Я пытаюсь установить положение горизонтального прокрутки, чтобы оно соответствовало нажатой кнопке. Я попытался использовать это, чтобы установить его безуспешно:

HorizontalScrollView hsv = (HorizontalScrollView)findViewById(R.id.ScrollView);
int x, y;
x = hsv.getLeft();
y = hsv.getTop();
hsv.scrollTo(x, y);

В результате ничего не происходит, scrollview не изменяется. 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>

Итак, если пятая кнопка нажата (которая выключена), когда начинается новая активность, я хочу установить новое представление, чтобы горизонтальное прокручивание было полностью справа от начала до конца влево.

Как установить положение горизонтального прокрутки?

Ответ 1

Прямо сейчас вы пытаетесь прокручивать в верхний левый угол 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:

Этот код не будет вести себя так, как вы ожидали бы, если он будет помещен в 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 создан, он автоматически раздувает и добавляет компоновку кнопок. Затем после вызова 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" />

И это макет buttons.xml, который автоматически накачивается MyHorizontalScrollView:

<?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>

Ответ 2

Хотя, это старый вопрос, я недавно столкнулся с той же проблемой и нашел еще одно, но менее сложное решение.

Предположим, что данный файл макета в исходном вопросе и предположим, что если действие начинается с данного макета, горизонтальное прокрутка прокрутки нужно прокрутить до кнопки 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);
            }
        });
    }
}