ยุบหรือขยาย CollapsingToolbarLayout โดยทางโปรแกรม


158

คำถามง่าย ๆ แต่ฉันไม่สามารถหาคำตอบได้ ฉันจะยุบหรือขยายCollapsingToolbarLayoutโปรแกรมได้อย่างไร

แถบเครื่องมือที่ยุบ

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

แถบเครื่องมือที่ขยาย


1
ฉันสงสัยในสิ่งเดียวกัน มันอาจเป็นเรื่องที่น่าสนใจที่จะขยายแถบเครื่องมือให้เต็มหน้าจอเมื่อผู้ใช้คลิกบนเค้าโครงที่ฝัง (เช่นรูปภาพ)
Moritz

คำตอบ:


321

เมื่อใช้ Support Library v23 คุณสามารถโทรappBarLayout.setExpanded(true/false)ได้

อ่านเพิ่มเติม: AppBarLayout.set ขยาย (บูลีน)


2
ตกลงขอบคุณสำหรับเคล็ดลับ แต่การสนับสนุน libs v23 เป็นรถม้าดังนั้นฉันไม่สามารถทดสอบได้ตอนนี้เพราะฉันต้องอยู่ใน 22.2.1 ....
Tomas

ตอนนี้คุณมี 23.0.1 พร้อมการแก้ไขบางอย่าง
Mario Velasco

6
เป็นไปได้ไหมที่จะกำหนดแอนิเมชั่นที่กำหนดเองด้วย libs สนับสนุน 23.1.1? setExpanded (บูลีนจริง) hav ภาพเคลื่อนไหวช้าจริงๆ ...
Nifhel

ฉันมีปัญหาที่ฉันมีเลย์เอาต์ที่มีแถบเครื่องมือที่พับได้และ recyclerview อยู่ข้างใต้ เมื่อลบรายการออกจาก recyclerview แถบเครื่องมือจะทำงานไม่เหมาะสมดังนั้นฉันจะขยายเค้าโครงของแถบแอปและทำงานได้อย่างถูกต้อง ฉันลงเอยด้วยการใช้ appBarLayout.set ขยาย (จริงจริง) สำหรับภาพเคลื่อนไหว
Ray Hunter

48

ฉันใช้รหัสนี้เพื่อยุบแถบเครื่องมือ ยังไม่สามารถหาวิธีขยายได้

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

แก้ไข 1: ฟังก์ชั่นเดียวกันกับความเร็วเชิงลบ Y แต่แถบเครื่องมือจะไม่ขยาย 100%และเป็นเท็จสำหรับพารามิเตอร์ล่าสุดควรทำงาน

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

แก้ไข 2: รหัสนี้ทำเพื่อฉัน

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 จะขยายแถบเครื่องมือ
  • onNestedPreScroll จะแสดงเนื้อหาภายในแถบเครื่องมือแบบขยาย

จะพยายามใช้ Behavior ด้วยตัวเอง


2
แก้ไข 1 ยังจะทำงานถ้าคุณตั้งค่าพารามิเตอร์สุดท้ายของการonNestedFling false
Ricky Lee

2
params.getBehavior () กำลังส่งคืน null ใน xml แท็ก layout_behaviour ถูกตั้งค่าไว้บน sibling NestedScrollView ไม่ใช่ AppBarLayout คุณสามารถช่วยฉันได้ไหม?
User31689

ขอบคุณ. แก้ไข 1 ทำงานอย่างถูกต้องหากพารามิเตอร์ล่าสุดเป็นเท็จ :)
Sirelon

@GobletSky ฉันประสบปัญหาเดียวกัน ฉันมี NestedScrollView ในส่วนของฉันและพยายามโทรonNestedFling ก่อนกำหนดชิ้นส่วน หลังจากตั้งค่าแฟรกเมนต์แล้วฉันสามารถเรียกเมธอดได้สำเร็จ
usp

@usp ที่จริงแล้วปัญหาของฉันแตกต่างไปจากเดิมอย่างสิ้นเชิง ดูสิ่งนี้: stackoverflow.com/questions/31067082/…
31899

27

คุณสามารถกำหนดว่าจะขยายหรือย่อส่วนด้วยตัวสร้างภาพเคลื่อนไหวของคุณเอง setTopAndBottomOffset(int)เพียงแค่ใช้

นี่คือตัวอย่าง:

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

2
นี่เป็นคำตอบเดียวที่ทำให้คุณสามารถสร้างออฟเซ็ตได้ ขอบคุณมาก!
Guilherme Torres Castro

2
appBar.set ขยาย (เท็จจริง); (เปิด / ปิดเคลื่อนไหว) คุณไม่จำเป็นต้องเขียนทุกบรรทัด
Puni

2
ถึง @Puni หากคุณต้องการขยาย / ยุบเพื่อชดเชย "กำหนดเอง" (เช่นการยุบหลายขั้นตอน) คุณจะต้องใช้สิ่งนี้
曾其威

นี่เป็นทางออกที่ดีที่สุดในการชดเชยแอปเคลื่อนไหวในกรณีที่คุณไม่ต้องการเขียนพฤติกรรมแบบกำหนดเอง การอัปเดตหนึ่งข้อมูลโค้ดคือการเรียกใช้ valueAnimator.setIntValues ​​() พร้อมกับ behavior.topAndBottomOffset ค่าเริ่มต้นแทนที่จะเป็น 0 เพื่อเริ่มการเคลื่อนไหวจากออฟเซ็ตของแอปบาร์ปัจจุบัน
reel

หากต้องการใช้ตัวแปรที่กำหนดเอง( -900 )เพื่อตั้งค่าvalueAnimator.setIntValuesโซลูชัน beter คือการใช้- ( appBar.getTotalScrollRange() )
Ali Rezaiyan

12

AppBarLayoutผมเคยเขียนส่วนขยายขนาดเล็กที่จะ จะช่วยให้การขยายและยุบของCollapsibleToolbarLayoutทั้งที่มีและไม่มีภาพเคลื่อนไหว ดูเหมือนว่าจะทำมันค่อนข้างถูกต้อง

รู้สึกอิสระที่จะลอง

เพียงแค่ใช้มันแทนของคุณและคุณสามารถเรียกวิธีการรับผิดชอบในการขยายหรือยุบตัวลงของAppBarLayoutCollapsingToolbarLayout

มันทำงานตรงตามที่คาดไว้ในโครงการของฉัน แต่คุณอาจต้องปรับแต่งค่าพุ่ง / เลื่อนในperform...วิธีการ (โดยเฉพาะอย่างยิ่งในperformExpandingWithAnimation()) CollapsibleToolbarLayoutไปพอดีกับคุณ


@ssdeno โปรดอ่าน Readme.md ของ Github Gist มันเลิกใช้แล้วตั้งแต่ v23 ของห้องสมุดสนับสนุน ตั้งแต่ V23 สนับสนุน (ดำเนินการ AndroidX) มีวิธีการในsetExpanded AppBarLayout
Bartek Lipinski

6

ใช้mAppBarLayout.setExpanded(true)เพื่อขยายแถบเครื่องมือและใช้mAppBarLayout.setExpanded(false)เพื่อยุบแถบเครื่องมือ

หากคุณต้องการที่จะเปลี่ยนCollapsingToolbarLayoutสูงโปรแกรมแล้วก็ใช้mAppBarLayout.setLayoutParams(params);

ขยาย:

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

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

ยุบ:

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

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

1
สิ่งนี้ช่วยฉันได้มาก
NoName

1
สิ่งนี้มีประโยชน์มาก ขอบคุณ!
sunlover3

5

สำหรับคนที่ต้องการทำงานกับ onNestedPreScroll และรับข้อผิดพลาดอย่างฉัน ฉันได้รับ NullPointerException ใน onCreate โดยไม่ต้องบรรทัดนี้

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

และทำงานไม่ถูกต้องกับสิ่งนี้ แต่ฉันแก้ไขปัญหานี้ด้วย

ใน onCreate:

        scrollToolbarOnDelay();

และ...

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


        }


0

สิ่งนี้อาจช่วยในการขยายหรือยุบ:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);

0

ฉันใช้สิ่งนี้

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

0

หากต้องการขยาย / ยุบ AppBarLayout โดยทางโปรแกรม:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.