web-dev-qa-db-ja.com

Android:ScrollViewの強制終了

ScrollViewを一番下から開始したいと思います。方法はありますか?

173
Noah Seidman

scroll.fullScroll(View.FOCUS_DOWN)も機能するはずです。

231
CommonsWare

次のようにscroll.post内でコードを実行する必要があります。

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

scroll.fullScroll(View.FOCUS_DOWN)はフォーカスの変更につながります。フォーカス可能なビューが複数ある場合、たとえば2つのEditTextがある場合、奇妙な動作が発生します。この質問には別の方法があります。

    View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
    int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
    int sy = scrollLayout.getScrollY();
    int sh = scrollLayout.getHeight();
    int delta = bottom - (sy + sh);

    scrollLayout.smoothScrollBy(0, delta);

これはうまく機能します。

Kotlin Extension

fun ScrollView.scrollToBottom() {
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY+ height)        
    smoothScrollBy(0, delta)
}
68
peacepassion

時々scrollView.postが機能しない

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

ただし、scrollView.postDelayedを使用すると、間違いなく機能します

 scrollView.postDelayed(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    },1000);
39
Ajay Shrestha

私に最適なのは

scroll_view.post(new Runnable() {
     @Override
     public void run() {
         // This method works but animates the scrolling 
         // which looks weird on first load
         // scroll_view.fullScroll(View.FOCUS_DOWN);

         // This method works even better because there are no animations.
         scroll_view.scrollTo(0, scroll_view.getBottom());
     }
});
35
https

完璧に動作するように増分します。

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

この答えは、Androidの本当に古いバージョンの回避策です。現在、 postDelayed にはそのバグはないため、使用する必要があります。

28
ademar111190

ビューがまだロードされていない場合、スクロールできません。上記のようにpostまたはsleep呼び出しで「後で」実行できますが、これはあまりエレガントではありません。

スクロールを計画し、次のonLayout()で実行することをお勧めします。ここにサンプルコード:

https://stackoverflow.com/a/10209457/131034

3
Frank

考慮すべきことの1つは、設定しないものです。子コントロール、特にEditTextコントロールには、RequestFocusプロパティが設定されていないことを確認してください。これは、レイアウト上の最後に解釈されたプロパティの1つであり、親(レイアウトまたはScrollView)の重力設定をオーバーライドします。

3
Epsilon3

下にスクロールする他の方法を次に示します

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

使用

既にレイアウトされているスクロールビューの場合

my_scroll_view.scrollToBottom()

Scrollviewのレイアウトが完了していない場合(例:Activity onCreate method ...で一番下までスクロールします)

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}
1
Phan Van Linh

質問に対する正確な答えではありませんが、EditTextにフォーカスが移ったらすぐにスクロールダウンする必要がありました。ただし、受け入れられた答えにより、ETはすぐにフォーカスを失うことになります(ScrollViewに対して)。

私の回避策は次のとおりです。

emailEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus){
            Toast.makeText(getActivity(), "got the focus", Toast.LENGTH_LONG).show();
            scrollView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scrollView.fullScroll(ScrollView.FOCUS_DOWN);
                }
            }, 200);
        }else {
            Toast.makeText(getActivity(), "lost the focus", Toast.LENGTH_LONG).show();
        }
    }
});
1
Teo Inke

実際、fullScrollを2回呼び出すとうまくいくことがわかりました。

myScrollView.fullScroll(View.FOCUS_DOWN);

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

最初の(失敗した)スクロールを実行した直後のpost()メソッドのアクティブ化に関係している可能性があります。この動作は、myScrollViewでの以前のメソッド呼び出しの後に発生するため、最初のfullScroll()メソッドを、関連する可能性のある他のメソッドで置き換えることができます。

1
BarLr

Kotlinコルーチンを使用してこれを行う別のクールな方法があります。 runnable(post/postDelayed)を持つHandlerとは対照的にコルーチンを使用する利点は、遅延アクションを実行するために高価なスレッドを起動しないことです。

launch(UI){
    delay(300)
    scrollView.fullScroll(View.FOCUS_DOWN)
}

コルーチンのHandlerContextをUIとして指定することが重要です。そうしないと、遅延アクションがUIスレッドから呼び出されない場合があります。

0
Phaestion

これらの場合、単にscroll.scrollTo(0、sc.getBottom())を使用していましたが機能しません。scroll.postを使用して使用してください

例:

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