Могу ли я прокручивать ScrollView программно в Android?

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

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

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

Ответ 1

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

или

sv.scrollTo(5, 10);

Ответ 2

Ответ от 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);
        } 
});

Ответ 3

Мне нужно, чтобы 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

Ответ 4

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

mScrollView.scrollBy(10, 10);

или

mScrollView.scrollTo(10, 10);

Ответ 5

Здесь есть много хороших ответов, но я хочу только добавить одну вещь. Иногда бывает, что вы хотите прокрутить свой 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, должны иметь только родительский элемент (например, Linear Layout).

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

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

но в этом случае вы не можете иметь гладкую прокрутку.

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

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

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

Ответ 9

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

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

Eg.

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

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

Ответ 10

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

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

Ответ 11

Добавление другого ответа, не связанного с координатами.

Это приведет к желаемому фокусу (но не к верхней позиции):

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

public void RequestChildFocus (просмотр дочернего объекта, просмотр сфокусирован)

дочерний - ребенок этого ViewParent, который хочет сосредоточиться. Это представление будет содержать сфокусированное представление. Это не обязательно то, что на самом деле имеет фокус.

сфокусировано - представление, которое является потомком ребенка, на самом деле имеющим фокус

Ответ 12

** для прокрутки до нужной высоты. Я придумал хорошее решение **

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

Ответ 13

просто прокрутка страницы:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);

Ответ 14

Каждый отправляет такие сложные ответы.

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

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

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

И, если необходимо, вы можете поместить вторую строку кода выше в runnable:

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

Мне потребовалось много исследований и игр, чтобы найти это простое решение. Надеюсь, это тоже поможет!:)

Ответ 15

Я использовал Runnable с sv.fullScroll(View.FOCUS_DOWN); Он отлично работает для непосредственной проблемы, но этот метод заставляет ScrollView отображать Focus со всего экрана, если вы делаете AutoScroll каждый раз, никакая EditText не сможет получать информацию от пользователя, в моем решении использовался другой код под runnable:

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

делая то же самое, не теряя внимания к важным представлениям

приветствия.

Ответ 16

это работает для меня

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

Ответ 17

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

Ответ 18

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

        }
    }