Чи можна прокручувати ScrollView програмно в Android?


145

Чи є якийсь спосіб прокрутити ScrollViewпрограму до певної позиції?

Я створив динаміку, TableLayoutяка розміщується в ScrollView. Тому я хочу, щоб у певній дії (наприклад, натискання кнопки тощо) конкретний рядок автоматично прокручувався до верхнього положення.

Це можливо?

Відповіді:


165
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

або

sv.scrollTo(5, 10);


43
Поєднуючи відповідь ercu та коментар до нього, найкращим способом здається:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
горобець

2
scrollTo () не призведе до повторного бажання. Слід піти з fullScroll ()
Аміт Ядав

3
Більш приємна прокрутка - із природним ефектом: sv.smoothScrollTo (5, 10)
ivan.panasiuk

205

Відповідь 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);
        } 
});

28
Я mScrollView.fullScroll(mScrollView.FOCUS_DOWN);успішно користувався.
amcc

3
Я можу підтвердити висновки Вантеля. mScrollView.fullScroll у публікації, яку можна виконати, зробив свою справу.
AlanKley

1
Відмінно! Дійсно, без Runnable це не вийшло. Тепер це працює! :)
Regis_AG

5
@HiteshDhamshaniya Якщо ви хочете плавно прокручувати, спробуйте mScrollView.smoothScrollTo(0, mScrollView.getBottom());.
Майк Ортіз

1
Навіщо це потрібно postтут?
Лютінг

35

Я хотів, щоб 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

або

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


23

Тут є багато хороших відповідей, але я хочу додати лише одне. Іноді трапляється, що ви хочете прокрутити свій 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);

але в цьому випадку ви не можете мати плавну прокрутку.

Я сподіваюся, що ця відповідь може допомогти комусь із тією ж проблемою.


1
@JohnT Рада, що вам це допомогло :)
Маттіа Руджеро



8

Якщо ви хочете миттєво прокрутити, ви можете скористатися:

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();
    }

що робить цей catchблок?
Джон Сардінья

1
Блок лову - це вилучення виключень під час прокрутки, якщо такі знайдені.
Меді

5

** для прокрутки до потрібної висоти. Я придумав хороше рішення **

                scrollView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.scrollBy(0, childView.getHeight());
                    }
                }, 100);

4

Я отримав це для роботи, щоб прокрутити донизу ScrollView (із TextView всередині):

(Я ставлю це до методу, який оновлює TextView)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
    myScrollView.post(new Runnable() {
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

4

Так, ти можеш.

Скажімо, у вас є одне 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

Примітка: якщо ви вже в потоці, вам потрібно створити новий потік для публікації, або він не прокручує нову довгу висоту до повного кінця (для мене). Наприклад:

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());*/
                }
            });
        }
    });
}

3

Додавання ще однієї відповіді, яка не передбачає координат.

Це призведе до фокусування бажаного виду (але не до вищої позиції):

  yourView.getParent().requestChildFocus(yourView,yourView);

public void RequestChildFocus (Перегляд дитини, зосереджено погляд)

дитина - дитина цього ViewParent, яка хоче зосередити увагу. Цей вид буде містити зосереджений вид. Не обов'язково погляд, який насправді має фокус.

сфокусований - погляд, який є нащадком дитини, який насправді має фокус


Саме те, що мені було потрібно, дякую. Перший фокус запиту для перегляду прокрутки, а потім scrollView.smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ());
Вулович Вукасін


2

Усі публікують такі складні відповіді.

Я знайшов просту відповідь для прокручування до низу, гарно:

final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);

// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );

І, якщо необхідно, ви можете помістити другий рядок коду, зверху, до запуску:

myScroller.post( new Runnable() {
    @Override
    public void run() {
        myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
    }
}

Мені знадобилося багато досліджень та роздумів, щоб знайти це просте рішення. Я сподіваюся, що і вам це допоможе! :)


1

Я використовував Runnable з sv.fullScroll (View.FOCUS_DOWN); Він ідеально підходить для негайної проблеми, але цей метод змушує ScrollView брати фокус з усього екрану, якщо ви робите автоматичний прокрутка щоразу, жоден EditText не зможе отримувати інформацію від користувача, моє рішення було використовувати інший код під прогоном:

sv.scrollTo (0, sv.getBottom () + sv.getScrollY ());

зробити те ж саме, не втрачаючи уваги на важливих поглядах

привітання.


0

це працює для мене

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

0
private int totalHeight = 0;

ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } else {
            loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        TotalHeight = loutMain.getMeasuredHeight();

    }
});

scrollMain.smoothScrollTo(0, totalHeight);

0
I had to create Interface

public interface ScrollViewListener {
    void onScrollChanged(ScrollViewExt scrollView, 
                         int x, int y, int oldx, int oldy);
}    

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

    public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomScrollView (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}




<"Your Package name ".CustomScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true"
    android:scrollbars="vertical">

    private CustomScrollView scrollView;

scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
        scrollView.setScrollViewListener(this);


    @Override
    public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
        // We take the last son in the scrollview
        View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
        int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

        // if diff is zero, then the bottom has been reached
        if (diff == 0) {
                // do stuff
            //TODO keshav gers
            pausePlayer();
            videoFullScreenPlayer.setVisibility(View.GONE);

        }
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.