Могу ли я прокрутить ScrollView программно в Android? - PullRequest
133 голосов
/ 22 июня 2011

Есть ли способ программно прокрутить ScrollView до определенной позиции?

Я создал динамический TableLayout, который помещается в ScrollView. Поэтому я хочу, чтобы для определенного действия (например, нажатия кнопки и т. Д.) Конкретная строка автоматически прокручивалась до верхней позиции.

Возможно ли это?

Ответы [ 18 ]

195 голосов
/ 31 декабря 2011

Ответ от Pragna не всегда работает, попробуйте это:

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.scrollTo(0, mScrollView.getBottom());
        } 
});

или

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
        } 
});

, если хотите перейти к началу

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_UP);
        } 
});
155 голосов
/ 22 июня 2011
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

или

sv.scrollTo(5, 10);

34 голосов
/ 15 мая 2013

Я хотел, чтобы scrollView прокручивался непосредственно после onCreateView () (а не после, например, нажатия кнопки). Чтобы заставить его работать, мне нужно было использовать ViewTreeObserver:

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

Но имейте в виду, что это будет вызываться каждый раз, когда что-то размещается (например, если вы устанавливаете представление невидимым или похожим), поэтому не забудьте удалить этот слушатель, если он вам больше не нужен:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) на SDK Lvl <16 </p>

или

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) в SDK Lvl> = 16

19 голосов
/ 22 июня 2011

Используйте что-то вроде этого:

mScrollView.scrollBy(10, 10);

или

mScrollView.scrollTo(10, 10);
18 голосов
/ 15 сентября 2016

Здесь много хороших ответов, но я хочу добавить только одну вещь.Иногда случается, что вы хотите прокрутить ScrollView до определенного вида макета, вместо полной прокрутки вверх или вниз.

Простой пример: в форме регистрации, если пользователь коснетсяКнопка «Регистрация», когда текст для редактирования формы не заполнен, вы хотите перейти к этому конкретному тексту для редактирования, чтобы сообщить пользователю, что он должен заполнить это поле.

В этом случае вы можете сделать что-то вродечто:

scrollView.post(new Runnable() { 
        public void run() { 
             scrollView.scrollTo(0, editText.getBottom());
        } 
});

или, если вы хотите плавную прокрутку вместо мгновенной прокрутки:

scrollView.post(new Runnable() { 
            public void run() { 
                 scrollView.smoothScrollTo(0, editText.getBottom());
            } 
    });

Очевидно, что вы можете использовать любой тип представления вместо Редактировать текст.Обратите внимание, что getBottom () возвращает координаты представления на основе его родительского макета, поэтому все представления, используемые внутри ScrollView, должны иметь только родителя (например, линейный макет).

Если у вас несколько родителей внутриДитя ScrollView, единственное решение, которое я нашел, это вызвать requestChildFocus в родительском представлении:

editText.getParent().requestChildFocus(editText, editText);

, но в этом случае у вас не может быть плавной прокрутки.этот ответ может помочь кому-то с той же проблемой.

9 голосов
/ 22 июня 2011

Попробуйте использовать scrollTo метод Подробнее

7 голосов
/ 11 декабря 2014

Если вы хотите прокрутить мгновенно, вы можете использовать:

ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());

            OR

scroll.fullScroll(View.FOCUS_DOWN);

            OR

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});

Или, если вы хотите плавно и медленно прокрутить, чтобы вы могли использовать это:

private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }
4 голосов
/ 07 мая 2015

Я получил это для работы, чтобы прокрутить до конца ScrollView (с TextView внутри):

(я поместил это в метод, который обновляет TextView)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
    myScrollView.post(new Runnable() {
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});
4 голосов
/ 16 октября 2017

Да, вы можете.

Допустим, у вас есть один Layout, а внутри него вы получите много Views.Поэтому, если вы хотите программно прокрутить до любого View, вам нужно написать следующий фрагмент кода:

Например.

content_main.xml

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/txtView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>

MainActivity.java

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);

Если вы хотите перейти к конкретному View скажем txtview в этом случае просто напишите:

scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());

И вы сделали. .

3 голосов
/ 15 июня 2014

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

void LogMe(final String s){
    runOnUiThread(new Runnable() {
        public void run() {
            connectionLog.setText(connectionLog.getText() + "\n" + s);
            final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
            sv.post(new Runnable() {
                public void run() {
                    sv.fullScroll(sv.FOCUS_DOWN);
                    /*
                    sv.scrollTo(0,sv.getBottom());
                    sv.scrollBy(0,sv.getHeight());*/
                }
            });
        }
    });
}
...