AndroidでScrollViewをプログラムでスクロールできますか?


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

2
scrollTo()は、欲望の再構築を生成しません。fullScroll()を使用する必要があります
Amit Yadav 14

3
より良いスクロールは自然な効果があります:sv.smoothScrollTo(
5、10

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 2013

1
優れた !実際、Runnableがなければ、機能しませんでした。今、それはうまくいきます!:)
Regis_AG

5
@HiteshDhamshaniyaスムーズなスクロールが必要な場合は、を試してくださいmScrollView.smoothScrollTo(0, mScrollView.getBottom());
Mike Ortiz

1
なぜpostここに必要なのですか?
2016年

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

ここには良い答えがたくさんありますが、1つだけ追加したいと思います。ScrollViewを、上または下に完全にスクロールするのではなく、レイアウトの特定のビューにスクロールしたい場合があります。

簡単な例:登録フォームで、フォームの編集テキストが入力されていないときにユーザーが「Signup」ボタンをタップした場合、その特定の編集テキストまでスクロールして、ユーザーにそのフィールドに入力する必要があることを伝えます。

その場合、次のようなことができます。

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よかった:)
Mattia Ruggiero



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ブロックは何をしますか?
John Sardinha

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

はい、できます。

あなたが1つ持っ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);

特定のにスクロールする場合は、txtviewとしViewましょう。この場合は、次のように記述します。

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


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

また、必要に応じて、上記のコードの2行目を実行可能コードに入れることができます。

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

この単純な解決策を見つけるには、多くの調査と遊んでいました。それもあなたに役立つことを願っています!:)


1

Runnableでsv.fullScroll(View.FOCUS_DOWN);を使用していました。それは当面の問題に対して完全に機能しますが、その方法では、ScrollViewが画面全体からフォーカスを取得します。そのAutoScrollを毎回発生させると、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);

        }
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.