Secara terprogram tutup atau perluas CollapsingToolbarLayout

159

Pertanyaan sederhana, tetapi saya tidak dapat menemukan jawaban. Bagaimana saya bisa menutup atau memperluas CollapsingToolbarLayoutprogram?

bilah alat diciutkan

↓^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~shjjjadi ↓^^^^^^^^^^~~~~~~~~~~~~~~~~~~~~

bilah alat yang diperluas

Tomas
sumber
1
Saya bertanya-tanya hal yang sama. Mungkin juga menarik untuk memperluas bilah alat ke layar penuh setelah pengguna mengklik tata letak yang disematkan (misalnya gambar).
Moritz

Jawaban:

322

Menggunakan Support Library v23, Anda dapat menelepon appBarLayout.setExpanded(true/false).

Bacaan lebih lanjut: AppBarLayout.setExpanded (boolean)

Jaxvy
sumber
2
Ok, terima kasih atas tipnya, tetapi dukungan libs v23 sangat buggy, jadi saya tidak dapat mengujinya sekarang, karena saya harus tetap menggunakan 22.2.1 ....
Tomas
Sekarang Anda memiliki 23.0.1 dengan beberapa perbaikan
Mario Velasco
6
Apakah mungkin untuk mendefinisikan animasi khusus dengan dukungan libs 23.1.1? setExpanded (boolean, true) memiliki animasi yang sangat lambat ...
Nifhel
Saya memiliki masalah di mana saya memiliki tata letak dengan bilah alat yang dapat dilipat dan recyclerview di bawahnya. Saat menghapus item dari tampilan ulang, bilah alat tidak berperilaku sesuai, jadi saya akan memperluas tata letak bilah aplikasi dan berfungsi dengan baik. Saya akhirnya menggunakan appBarLayout.setExpanded (true, true) untuk animasi.
Ray Hunter
48

Saya menggunakan kode ini untuk menyusutkan bilah alat. Masih tidak dapat menemukan cara untuk mengembangkannya.

public void collapseToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, 10000, true);
    }
}

Sunting 1: Fungsi yang sama dengan kecepatan negatifY tetapi bilah alat tidak diperluas 100% dan false untuk param terakhir harus berfungsi

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, -10000, false);
    }
}

Sunting 2: Kode ini melakukan trik untuk saya

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.setTopAndBottomOffset(0);
        behavior.onNestedPreScroll(rootLayout, appbarLayout, null, 0, 1, new int[2]);
    }
}
  • setTopAndBottomOffset lakukan perluas bilah alat
  • onNestedPreScroll menampilkan konten di dalam bilah alat yang diperluas

Akan mencoba menerapkan Perilaku sendiri.

Tuấn Trần Anh
sumber
2
Sunting 1 juga akan berfungsi jika Anda mengatur parameter terakhir onNestedFlingke false.
Ricky Lee
2
params.getBehavior () mengembalikan nol. Dalam xml, tag layout_behaviour diatur pada saudara NestedScrollView, bukan AppBarLayout. Bisakah kamu membantuku?
Pengguna31689
Terima kasih. Edit 1 berfungsi dengan baik, jika param terakhir salah. :)
Sirelon
@ GobletSky Saya menghadapi masalah yang sama. Saya memiliki NestedScrollView di fragmen saya dan mencoba menelepon onNestedFling sebelum mengatur fragmen. Setelah mengatur fragmen, saya dapat memanggil metode dengan sukses.
usp
@ Usp Sebenarnya, masalah saya sama sekali berbeda (kesalahan agak noobish). Lihat ini: stackoverflow.com/questions/31067082/…
User31689
27

Anda dapat menentukan seberapa banyak itu mengembang atau runtuh dengan animator khusus Anda. Cukup gunakan setTopAndBottomOffset(int).

Berikut ini sebuah contoh:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBar.getLayoutParams();
final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
if (behavior != null) {
    ValueAnimator valueAnimator = ValueAnimator.ofInt();
    valueAnimator.setInterpolator(new DecelerateInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            behavior.setTopAndBottomOffset((Integer) animation.getAnimatedValue());
            appBar.requestLayout();
        }
    });
    valueAnimator.setIntValues(0, -900);
    valueAnimator.setDuration(400);
    valueAnimator.start();
}
Gerhard
sumber
2
Ini adalah satu-satunya jawaban yang benar-benar memungkinkan Anda menghidupkan offset khusus. Terimakasih banyak!
Guilherme Torres Castro
2
appBar.setExpanded (false, true); (buka / tutup, bernyawa) Anda tidak perlu menulis semua kalimat itu
Puni
2
ke @Puni, jika Anda ingin memperluas / menutup ke offset "khusus" (seperti melakukan beberapa tahapan runtuh), Anda memerlukan ini.
曾 其 威
Ini adalah solusi terbaik untuk menghidupkan offset AppBar jika Anda tidak ingin menulis perilaku khusus. Satu pembaruan untuk cuplikan kode adalah dengan memanggil valueAnimator.setIntValues ​​() dengan behavior.topAndBottomOffset nilai awal alih-alih 0 untuk memulai animasi dari offset appbar saat ini.
Gulungan
Untuk menggunakan variabel khusus ( -900 )untuk mengatur valueAnimator.setIntValuesSolusi beter adalah menggunakan- ( appBar.getTotalScrollRange() )
Ali Rezaiyan
12

Saya telah menulis ekstensi kecil untuk AppBarLayout. Hal ini memungkinkan untuk memperluas dan memecah CollapsibleToolbarLayoutkeduanya dengan dan tanpa animasi. Tampaknya melakukannya dengan benar.

Jangan ragu untuk mencobanya.

Gunakan saja alih-alih Anda AppBarLayout, dan Anda dapat memanggil metode yang bertanggung jawab untuk meluaskan atau menciutkan CollapsingToolbarLayout.

Ini bekerja persis seperti yang diharapkan dalam proyek saya, tetapi Anda mungkin perlu mengubah nilai fling / scroll dalam perform...metode (terutama di performExpandingWithAnimation()) agar cocok dengan Anda CollapsibleToolbarLayout.

Bartek Lipinski
sumber
@ssdeno tolong baca Readme.md dari inti Github. Sudah usang sejak v23 dari perpustakaan Dukungan. Sejak v23 dari Dukungan (melanjutkan ke AndroidX), ada setExpandedmetode di AppBarLayout.
Bartek Lipinski
6

Gunakan mAppBarLayout.setExpanded(true)untuk memperluas Toolbar dan gunakan mAppBarLayout.setExpanded(false)untuk menutup Toolbar.

Jika Anda ingin mengubah ketinggian CollapsingToolbarLayout secara terprogram maka gunakan saja mAppBarLayout.setLayoutParams(params);

Memperluas:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*200; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(true);

Jatuh:

CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*80; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(false);
Ferdous Ahamed
sumber
1
Ini sangat membantu saya.
NoName
1
Ini sangat membantu. Terima kasih!
sunlover3
5

untuk orang-orang yang ingin bekerja dengan onNestedPreScroll dan dapatkan kesalahan seperti saya. saya mendapatkan NullPointerException di onCreate tanpa baris ini

    CoordinatorLayout coordinator =(CoordinatorLayout)findViewById(R.id.tab_maincontent);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
    //below line
    params.setBehavior(new AppBarLayout.Behavior() {});

dan tidak bekerja dengan baik dengan ini. tetapi saya mengatasi masalah ini dengan

di onCreate:

        scrollToolbarOnDelay();

dan...

    public void scrollToolbarOnDelay() {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.tab_appbar);
                    CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.tab_maincontent);
                    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
                    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
         if(behavior!=null)
                    behavior.onNestedPreScroll(coordinator, appBarLayout, null, 0, 100, new int[]{0, 0});
         else
            scrollToolbarOnDelay()
                }
            }, 100);


        }
Sepehr Nozaryian
sumber
1

Coba ini...

Memperluas

appBarLayout.setExpanded(true, true);

Untuk mengingat

appBarLayout.setExpanded(false, true);
Victor Sam VS
sumber
0

Ini dapat membantu memperluas atau menciutkan:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);
ROHIT LIEN
sumber
0

Saya sudah menggunakan ini

 private fun collapseAppbar() {
        scrollView.postDelayed(Runnable {
            scrollView?.smoothScrollTo(50, 50)
        }, 400)
    }
deniz
sumber
0

Untuk memperluas / menciutkan AppBarLayout secara terprogram:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
avisper
sumber