Android: Gaya ScrollView ke bawah


Jawaban:


274

scroll.fullScroll(View.FOCUS_DOWN) juga harus bekerja.

Masukkan ini ke dalam a scroll.Post(Runnable run)

Kode Kotlin

scrollView.post {
   scrollView.fullScroll(View.FOCUS_DOWN)
}

6
Tampaknya tidak melakukan apa-apa, saran? Saya mencobanya di onCreate dan kemudian di onClick sebuah tombol.
RichardJohnn

Tampaknya tidak berhasil mengubah orientasi. Kalau tidak berfungsi.
Prashant

1
Ini tidak berfungsi jika ukuran tata letak telah berubah tepat sebelum memanggilnya. Itu perlu diposting sebagai gantinya.
MLProgrammer-CiM

2
Ini dan di bawah ini, tidak akan berfungsi sampai Anda memberi waktu pada pandangan untuk mengembang sepenuhnya, hanya menyederhanakan jawaban ademar. scrollView.postDelayed (Runnable baru () {@Override public void run () {scrollView.fullScroll (View.FOCUS_UP // Atau Down);}}, 1000);
EngineSense

scroll.fullScroll (View.FOCUS_DOWN) akan mengarah pada perubahan fokus. Itu akan membawa beberapa perilaku aneh ketika ada lebih dari satu tampilan yang bisa fokus, misalnya dua EditText. Periksa solusi lain yang saya berikan di bagian bawah.
peacepassion

332

Anda harus menjalankan kode di dalam scroll.post seperti ini:

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

4
ada beberapa cara tanpa kehilangan fokus elemen saat ini, ketika saya melakukan ini saya kehilangan fokus elemen saya saat ini (berbeda dari scrollview)
rkmax

2
Ini diperlukan hanya dalam kasus di mana tata letak belum diukur dan ditata (misalnya jika Anda menjalankannya di onCreate). Dalam kasus seperti menekan tombol, .post () tidak diperlukan.
Patrick Boos

12
Jika Anda tidak ingin fokus pada ScrollView, Anda dapat menggunakan scroll.scrollTo(0, scroll.getHeight());untuk melompat ke bawah, atau scroll.smoothScrollTo(0, scroll.getHeight());untuk scroll yang lebih halus
yuval

Bukankah kode ini kemungkinan kebocoran memori? Sebuah Runnable anonim dibuat yang menyimpan referensi ke tampilan aktivitas (gulir). Jika aktivitas hancur ketika runnable menjalankan tugasnya, itu akan membocorkan referensi ke scrollview, bukan?
Jenever

Di Kotlin:scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
Albert Vila Calvo

94

scroll.fullScroll(View.FOCUS_DOWN)akan mengarah pada perubahan fokus. Itu akan membawa beberapa perilaku aneh ketika ada lebih dari satu tampilan yang bisa fokus, misalnya dua EditText. Ada cara lain untuk pertanyaan ini.

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

Ini bekerja dengan baik.

Perpanjangan Kotlin

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

Senang saya tidak perlu membuang waktu lagi untuk ini. Apa yang saya butuhkan
Alexandre G

6
Ini seharusnya memiliki lebih banyak suara positif. Ini adalah jawaban terbaik sejauh ini.
Eric Lange

1
Ini adalah jawaban terbaik yang ada di sini.
void pointer

1
Sudah mencoba semua yang lain di halaman ini, bahkan barang-barang di bawah ini. Ini adalah satu-satunya hal yang berhasil, dan itu tidak menyebabkan EditText saya kehilangan fokus. Terima kasih.
Joel

Jika Anda perlu menggulir ke bawah saat keyboard muncul, gabungkan kode ini dengan perpustakaan ini . Bekerja seperti pesona.
wonsuc

47

Terkadang scrollView.post tidak berfungsi

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

TETAPI jika Anda menggunakan scrollView.postDelayed, itu pasti akan berfungsi

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

terima kasih untuk identifikasi. postDelayed adalah solusi yang lebih baik.
Prashant

@Pashash :) :) :)
Ajay Shrestha

1
Ingatlah bahwa Anda harus membuang Runnable Anda saat Anda menyelesaikan aktivitas
FabioR

38

Apa yang paling berhasil bagi saya adalah

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

Saya mencoba ini, tetapi algoritma di sini salah. Tolong periksa jawaban saya di bagian bawah.
peacepassion

28

Saya menambahkan untuk bekerja dengan sempurna.

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

Catatan

Jawaban ini merupakan solusi untuk Android versi lama. Hari postDelayedini tidak ada lagi bug dan Anda harus menggunakannya.


3
Tidak di atas dua, tetapi ini berfungsi baik di ponsel saya (LG JellyBean 4.1.2 Optimus G).
Youngjae

9
Mengapa tidak menggunakan scrollView.postDelayed (runnable, 100)?
Matt Wolfe

1
@MattWolfe pada saat itu tidak berfungsi di beberapa versi lama Android. Tetapi hari ini jawaban ini sudah usang sama sekali.
ademar111190

4
Demi kasih tuhan, gunakan scrollView.postDelayed (runnable, 100)! :)
Alex Lockwood

1
Saya menambahkan catatan @AlexLockwood Saya harap orang-orang menggunakan postDelayed:)
ademar111190

4

Saya mencoba yang berhasil.

scrollView.postDelayed(new Runnable() {
    @Override
    public void run() {
        scrollView.smoothScrollTo(0, scrollView.getHeight());
    }
}, 1000);

3

Saat tampilan belum dimuat, Anda tidak dapat menggulir. Anda dapat melakukannya 'nanti' dengan postingan atau panggilan tidur seperti di atas, tetapi ini tidak terlalu elegan.

Lebih baik untuk merencanakan gulir dan melakukannya pada onLayout berikutnya (). Contoh kode di sini:

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


3

Satu hal yang perlu dipertimbangkan adalah apa yang TIDAK diatur. Pastikan kontrol anak Anda, terutama kontrol EditText, tidak memiliki properti RequestFocus yang ditetapkan. Ini mungkin salah satu properti yang ditafsirkan terakhir pada tata letak dan itu akan menimpa pengaturan gravitasi pada orang tuanya (tata letak atau ScrollView).


3

Berikut ini beberapa cara lain untuk menggulir ke bawah

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

Menggunakan

Jika Anda scrollview sudah ditata

my_scroll_view.scrollToBottom()

Jika scrollview Anda belum selesai ditata (mis: Anda gulir ke bawah dalam onCreatemetode Aktivitas ...)

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}

1

Bukan jawaban untuk pertanyaan itu, tetapi saya perlu menggulir ke bawah segera setelah EditText mendapatkan fokus. Namun jawaban yang diterima akan membuat ET juga kehilangan fokus segera (menurut saya ScrollView).

Solusi saya adalah sebagai berikut:

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

Saya benar-benar menemukan bahwa memanggil fullScroll dua kali berhasil:

myScrollView.fullScroll(View.FOCUS_DOWN);

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

Mungkin ada hubungannya dengan aktivasi metode post () setelah melakukan scroll pertama (tidak berhasil). Saya pikir perilaku ini terjadi setelah pemanggilan metode sebelumnya pada myScrollView, jadi Anda dapat mencoba mengganti metode fullScroll () pertama dengan hal lain yang mungkin relevan bagi Anda.


0

Menggunakan ada cara keren lain untuk melakukan ini dengan coroutine Kotlin. Keuntungan menggunakan coroutine yang bertentangan dengan Handler dengan runnable (post / postDelayed) adalah tidak menjalankan utas mahal untuk melakukan tindakan yang tertunda.

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

Penting untuk menentukan HandlerContext coroutine sebagai UI jika tidak, tindakan yang tertunda mungkin tidak dipanggil dari utas UI.


0

Dalam kasus itu hanya menggunakan scroll.scrollTo (0, sc.getBottom ()) tidak berfungsi, gunakan scroll.post

Contoh:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.