ViewPager ใน NestedScrollView


111

ฉันต้องการสร้างอินเทอร์เฟซเช่น Google Newsstand ซึ่งเป็น ViewPager ประเภทหนึ่ง (เลื่อนแนวนอน) บนส่วนหัวที่ยุบลง (เลื่อนแนวตั้ง) ข้อกำหนดอย่างหนึ่งของฉันคือการใช้ไลบรารีการสนับสนุนการออกแบบใหม่ที่นำเสนอใน Google IO 2015 ( http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

จากตัวอย่างที่สร้างโดย Chris Banes ( https://github.com/chrisbanes/cheesesquare ) ฉันมาถึงจุดที่ฉันสามารถทำพฤติกรรมการยุบตัวได้ แต่ด้วย LinearLayout พื้นฐาน (ไม่มีการเลื่อนแนวนอน)

ฉันพยายามแทนที่ LinearLayout ด้วย ViewPager และได้หน้าจอว่างเปล่า ฉันเล่นกับ: ความกว้างน้ำหนักและกลุ่มมุมมองทุกประเภท แต่ .... ยังคงเป็นหน้าจอว่างเปล่า ดูเหมือนว่า ViewPager และ NestedScrollView จะไม่ชอบกันและกัน

ฉันลองวิธีแก้ปัญหาโดยใช้ HorizontalScrollView มันใช้งานได้ แต่ฉันใช้ประโยชน์จากคุณสมบัติ PagerTitleStrip และโฟกัสไปที่แผงเดียว (ฉันสามารถหยุดแนวนอนระหว่าง 2 แผงได้)

ตอนนี้ฉันไม่มีความคิดอีกแล้วถ้าใครสามารถนำฉันไปสู่การแก้ปัญหา ...

ขอบคุณ

นี่คือไฟล์เลย์เอาต์ล่าสุดของฉัน:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/header_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <include
                layout="@layout/part_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/activity_main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/activity_main_nestedscrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.view.ViewPager
            android:id="@+id/activity_main_viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFA0"/>


    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

คุณลองห่อViewPagerภายในของคุณLinearLayoutหรือยัง? แค่อยากรู้ว่าจะแสดงผลViewPagerอย่างถูกต้องหรือไม่
CzarMatt

ใช่ฉันลองแล้ว แต่ก็ยังได้ผลลัพธ์เหมือนเดิม ฉันทำการทดสอบหลายอย่างกับส่วนประกอบมากมาย แต่ ViewPager ไม่เคยแสดงผลใน NestedScrollView ไม่ว่าลำดับชั้นจะเป็นอย่างไร
Kyso84

ฉันเพิ่งสร้างแอปทดสอบโดยมีรูปแบบViewPagerภายในNestedScrollViewเป็นเพียงรูปแบบเดียว - ดูเหมือนจะทำงานได้ดี ฉันยังสามารถลงสู่DrawerLayoutความสำเร็จ บางทีโค้ดของคุณอาจมีลักษณะอื่นที่ขัดขวางฟังก์ชันที่คุณต้องการ ต้องการแบ่งปันแหล่งที่มาของคุณมากขึ้นหรือไม่?
CzarMatt

ว้าวคุณสามารถปัดไปทางซ้าย / ขวาและขึ้น / ลงได้หรือไม่? ฉันใช้ FragmentPagerAdapter เพื่อแสดงชิ้นส่วนในเพจเจอร์ของฉัน คุณแชร์โค้ดตัวอย่างแทนได้ไหม
Kyso84

ฉันวางเค้าโครงตัวอย่างง่ายๆที่นี่: pastebin.com/jXPw6mtf Edit: คุณสามารถโหลดส่วนใดก็ได้ที่คุณต้องการในไฟล์ViewPager. ฉันสามารถเลื่อนมุมมองขึ้นลงรวมถึงเลื่อนไปViewPagerทางซ้าย / ขวา
CzarMatt

คำตอบ:


128

ฉันพบปัญหานี้ฉันแก้ปัญหาโดย setFillViewport (true)

<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/nest_scrollview"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="mio.kon.yyb.nestedscrollviewbug.ScrollingActivity"
tools:showIn="@layout/activity_scrolling">


    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

ในกิจกรรม

  NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nest_scrollview);
    scrollView.setFillViewport (true);

ใส่คำอธิบายภาพที่นี่


31
โปรดทราบว่าสิ่งนี้สามารถตั้งค่าใน XML ได้เช่นกันเพียงแค่เพิ่มลงandroid:fillViewport="true"ในNestedScrollViewวัตถุ เอกสารDefines whether the scrollview should stretch its content to fill the viewport.อธิบายคุณลักษณะนี้เป็น
Krøllebølle

7
สิ่งนี้ไม่ได้ช่วยแก้ปัญหาการเลื่อนในส่วนของตัวยึดตำแหน่ง
Atieh

3
ขอบคุณ! ผมได้นั่งandroid:fillViewport="true"บนNestedScrollViewและภายในfragmentฉันมีlistViewที่ฉันนั่งandroid:nestedScrollingEnabled="true".. แก้ไขปัญหาการเลื่อน
radubogdan

@ Krøllebølle NestedScrollView ไม่มีแอตทริบิวต์นี้คุณต้องตั้งค่าโดยใช้โปรแกรม

ใช่สิ่งนี้ใช้ได้กับฉัน ฉันมีปัญหาเมื่อตั้งค่าความสูงของ viewpager เป็น match_parent ภายใน NestedScrollView มันไม่แสดงมุมมอง
Waheed Nazir

71

โอเคฉันทำตัวอย่างเล็ก ๆ ด้วยViewPagerและNestedScrollView. ปัญหาที่ฉันประสบคือความสูงViewPagerและListView. ฉันจึงทำการปรับเปลี่ยนListViewและViewPager'sวัดส่วนสูงเล็กน้อย

หากใครต้องการดูโค้ดนี่คือลิงค์: https://github.com/TheLittleNaruto/SupportDesignExample/

เอาท์พุต:

ใส่คำอธิบายภาพที่นี่


ใช้งานไม่ได้ถ้าส่วนย่อยไม่มี listview แม้ forlistview จะใช้งานได้หากจำนวนรายการเหมือนกันสำหรับชิ้นส่วนทั้งหมด
Pankaj Arora

3
ฉันอาจจะไปงานปาร์ตี้ช้าไปหน่อยแต่วันนี้ฉันทำงานอยู่และฉันได้รับมัน (ส่วนใหญ่) ทำงานกับการเพิ่มแอป: layout_behavior = "@ string / appbar_scrolling_view_behavior" ทั้งใน ViewPager และในมุมมองหลักของ แต่ละชิ้นส่วน
Graeme

1
ไม่ต้องสงสัยเลยว่าวิธีนี้ใช้งานได้ แต่ปัญหานี้ไม่ได้ซับซ้อนเกินไปหรือไม่? ฉันแก้ไขสิ่งนี้โดยการกำจัดNestedScrollViewและใช้ a LinearLayoutแทน อะไรคือประโยชน์ของการมีNestedScrollViewover a LinearLayoutถ้าจุดประสงค์ทั้งหมดคือการเลื่อนเนื้อหาภายใน ViewPager? กรุณาแก้ไขฉันถ้าฉันผิด : x ขอบคุณ
ตะคริว

1
ขอบคุณมาก! ฉันอยู่ในจุดที่ต้องดึงผมออกและ WrapContentHeightViewPager ของคุณทำงานได้อย่างมีเสน่ห์ ฉันเป็นหนี้คุณ!
Mavamaarten

1
โซลูชั่นที่สมบูรณ์แบบ ขอบคุณ. มันได้ผลสำหรับฉัน .. :)
Mrunal

42

เพิ่ม android:fillViewport="true"ในNestedScrollViewไฟล์. งวด.


3
มันแก้ปัญหาได้ แต่ความสูงของ viewpager จะเป็นพาเรนต์ที่ตรงกัน (ใช้ความสูงทั้งหน้า)
Manukumar

27

แทนที่จะวาง ViewPager ไว้ใน NestedScrollView ให้ทำในทางกลับกัน

วาง NestedScrollView ในมุมมองลูกภายใน ViewPager ซึ่งโดยพื้นฐานแล้วคือเค้าโครงของ Fragment นอกจากนี้ยังมีโอกาสมากที่คุณจะไม่จำเป็นต้องใช้ NestedScrollView ด้วยซ้ำหากเค้าโครงรายการของ Fragment นั้นเรียบง่ายมาก

ตัวอย่างเลย์เอาต์

เค้าโครงของกิจกรรม:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="@dimen/app_bar_height"
                android:scaleType="centerCrop"
                android:src="@drawable/my_bg"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.8"
                app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.design.widget.TabLayout
            android:id="@+id/content_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

หากคุณไม่ต้องการ TabLayout คุณสามารถทิ้ง LinearLayout และทำให้ ViewPager เป็นแบบสแตนด์อโลนได้ แต่อย่าลืมใช้app:layout_behavior="@string/appbar_scrolling_view_behavior"ในแอตทริบิวต์ ViewPager

เค้าโครงของ Simple Fragment:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

เค้าโครงของ Complex Fragment:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World"/>
    </RelativeLayout>
</android.support.v4.widget.NestedScrollView>

ตัวอย่าง App: CollapsingToolbarPoc

ใส่คำอธิบายภาพที่นี่


นี่คือสิ่งที่ทำเพื่อฉัน ขอบคุณ!
rjr-apps

เฮ้ Ino ดูเหมือนจะใช้งานได้ แต่เมื่อฉันเพิ่มอีกหนึ่งมุมมองที่ด้านบนของ TabLayout มันก็แตก คุณสามารถให้ความช่วยเหลือได้หรือไม่?
hushed_voice

คุณได้บันทึกวันของฉัน :)
androidXP

20

มีปัญหาเดียวกัน

เมื่อวาง NestedScrollView รอบ ๆ ViewPager มันจะไม่ทำงาน

สิ่งที่ DID ทำงานแม้ว่าจะวาง NestedScrollView ไว้ในเลย์เอาต์ของส่วนที่ฉันกำลังโหลดภายใน ViewPager

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@id/fragment_detail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            android:orientation="vertical">
    ...Content...
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>


ใช้งานได้หรือไม่หากเนื้อหาเป็นโครงร่างผู้ประสานงานกับ NestedScrollView อื่น และ CoordinatorLayout ผู้ปกครองฟังเหตุการณ์เลื่อนที่นั่นหรือไม่
Atieh

งานนี้สำหรับฉัน ฉันเพิ่ม NestedScrollView ลงในทุกรายการของ ViewPager ของฉันแทน ViewPager ขอบคุณ.
jerogaren

ฉันมีรูดเฟรชเลย์เอาต์ในแฟรกเมนต์ตามวิธีแก้ปัญหาของคุณฉันใส่ NestedScrollview ในแฟรกเมนต์เหนือรูดรีเฟรชเลย์เอาต์ .. จากนั้นข้อมูลจะไม่ถูกโหลด มันไม่ได้ผล
Palak Darji

16

คุณสามารถลองเช่นนี้ viewpager ทำงานได้ดี แต่ความสูงของ viewpager คงที่

ฉันยังคงพบวิธีแก้ปัญหาที่ดีกว่า ... โปรดแจ้งให้เราทราบว่ามีจุดใดที่สามารถทำได้ดีกว่านี้ขอบคุณ

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="800dp"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

คุณพยายามที่จะห่อหุ้มไว้ใน "android.support.design.widget.CoordinatorLayout" และแถบเครื่องมือที่ยุบหรือไม่
Kyso84

วิธีแก้ปัญหาของคุณดูเหมือนจะพิสูจน์ได้ว่าปัญหาอยู่ที่ความสูง พบการปรับปรุงใด ๆ หรือยัง @Paul?
jasxir

3
อันนี้ใช้ได้ผลสำหรับฉัน แต่ฉันก็ต้องเรียก setFillViewport (true) ใน Nestedview ด้วย
larrytech

12

ฉันมีปัญหาเดียวกันและเพิ่งแก้ไขด้วยการเปลี่ยนแปลงบางอย่าง ViewPagerไม่ทำงานภายในไฟล์NestedScrollView. ใส่เพียงแค่คุณเป็นเด็กโดยตรงของคุณViewPager CoordinatorLayoutจากนั้นเนื้อหาสำหรับ Fragment ของ ViewPager แต่ละชิ้นควรอยู่ในNestedScrollView. แค่นั้นแหละ.


แม้ว่าเนื้อหาจะเป็นเค้าโครงผู้ประสานงานกับ NestedScrollView อื่น?
Atieh

1
ไม่ได้โหลดข้อมูล Fragment listview ด้วยวิธีนี้!
Palak Darji

5

คุณไม่จำเป็นต้องใช้ NestedScrollView เพื่อให้มีเอฟเฟกต์พารัลแลกซ์ ลองทำสิ่งนี้:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true">

        <android.support.v7.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways"/>

        <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/my_tab_layout"
            android:fillViewport="false"
            app:tabMode="fixed"/>
     </android.support.design.widget.AppBarLayout>

            <android.support.v4.view.ViewPager
                android:id="@+id/my_view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</android.support.design.widget.CoordinatorLayout>

3
สิ่งนี้จะใช้ได้ตราบเท่าที่ViewPagerชิ้นส่วนทั้งหมดของคุณเป็นอีเธอRecyclerViewร์หรือNestedScrollView. หากไม่เป็นเช่นListViewนั้น(เช่น) วิธีแก้ปัญหาสำหรับ Lollipop ขึ้นไปคือการโทรlistView.setNestedScrollingEnabled(true)
AndyDeveloper

ในที่สุดสิ่งที่ใช้งานได้โดยไม่ต้องเพิ่มคอนเทนเนอร์เลื่อนพิเศษ! Btw คุณสามารถตั้งค่า setNestedScrollingEnabled (true) นี้ใน xml ได้ด้วย: android: nestedScrollingEnabled = "true"
Analizer

1
ถ้าฉันเรียกใช้แอพของฉันให้ยุบแถบเครื่องมือในขณะที่อยู่ในแท็บเดียวสลับแท็บจากนั้นดึงแถบเครื่องมือกลับลงมันว่างเปล่า ต้องเปลี่ยนแท็บในขณะที่อยู่ในสถานะไม่ยุบเพื่อให้กลับมาอีกครั้ง ใกล้แล้ว แต่จนถึงตอนนี้ :(
ฉัน -

4

ฉันมีเค้าโครงที่มีแถบเครื่องมือแอปที่มี NestedScrollView อยู่ด้านล่างจากนั้นภายในแถบเครื่องมือที่ซ้อนกันจะเป็น LinearLayout ด้านล่าง LinearLayout เป็นเพจเจอร์สำหรับดู แนวคิดคือ LinearLayout ภายใน NestedScrollView ได้รับการแก้ไข - คุณสามารถเลื่อนไปทางซ้าย / ขวาระหว่างมุมมองของเพจเจอร์มุมมองได้ แต่เนื้อหานี้จะไม่เคลื่อนที่ในแนวนอนอย่างน้อยที่สุด คุณควรจะยังคงสามารถเลื่อนเนื้อหาทั้งหมดในแนวตั้งได้เนื่องจากมุมมองการเลื่อนแบบซ้อนกัน นั่นคือความคิด ดังนั้นฉันจึงตั้งค่าความสูง NestedScrollView ที่ซ้อนกันเป็น match_parent เติมวิวพอร์ตจากนั้นเค้าโครงลูกทั้งหมด / ViewPager เป็น wrap_content

ในหัวของฉันถูกต้อง แต่มันไม่ได้ผล - ViewPager อนุญาตให้ฉันไปทางซ้าย / ขวา แต่ไม่มีการเลื่อนแนวตั้งไม่ว่าเนื้อหาของหน้า viewpager จะดันอยู่ด้านล่างด้านล่างของหน้าจอปัจจุบันหรือไม่ก็ตาม ปรากฎว่าเป็นเพราะ ViewPager ไม่เคารพ wrap_content ในหน้าต่างๆ

ฉันได้รอบนี้โดยการคลาสย่อย ViewPager เพื่อให้มันเปลี่ยนความสูงโดยขึ้นอยู่กับรายการที่เลือกในปัจจุบันประเภทของการบังคับให้มันทำงานเช่น layout_height = "wrap_content":

public class ContentWrappingViewPager extends ViewPager {

    public ContentWrappingViewPager(Context context) {
        super(context);
    }

    public ContentWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

โซลูชันได้รับแรงบันดาลใจจากคำตอบนี้ ทำงานให้ฉัน!


แต่มุมมองการเลื่อนจะเลื่อนไปด้านบนโดยอัตโนมัติ? จะแก้ไขอย่างไร?
Vivek Kumar

4

เพียงแค่ใส่บรรทัดนี้ใน NestedScrollView

android:fillViewport="true"

ขอบคุณมากมาย จะทำอย่างไรถ้าต้องการเลื่อนโดยแตะ CollapsingToolbarLayout โดยตรง
Pratik Saluja

3

ฉันลบNestedScrollViewออกจากเลย์เอาต์หลักและแทรกเป็นParentในเลย์เอาต์Fragmentทั้งหมดที่ควรจะโหลดในViewPager ได้แก้ไขปัญหานี้ให้ฉัน


3

ใช้คลาสที่กำหนดเองด้านล่างเพื่อแก้ไขปัญหาของคุณ อย่าลืมเรียกใช้เมธอด onRefresh () ใน pagechangelistener

public class ContentWrappingViewPager extends ViewPager
{
    private int width = 0;
    public ContentWrappingViewPager(Context context) {
        super(context);
    }

    public ContentWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int height = 0;
        width = widthMeasureSpec;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void onRefresh()
    {
        try {
            int height = 0;
            if (getChildCount() > getCurrentItem()) {
                View child = getChildAt(getCurrentItem());
                child.measure(width, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                int h = child.getMeasuredHeight();
                if(h > height) height = h;
            }

            int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            ViewGroup.LayoutParams layoutParams = this.getLayoutParams();
            layoutParams.height = heightMeasureSpec;
            this.setLayoutParams(layoutParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2

ฉันมีปัญหาที่คล้ายกัน (แต่ไม่มีCollapsingToolbarLayoutเพียงแค่Toolbar+ TabLayoutภายในAppBarLayout) ฉันต้องการให้แถบเครื่องมือเลื่อนออกไปให้พ้นสายตาเมื่อเลื่อนลงเนื้อหาของViewPagerไฟล์NestedScrollView.

เค้าโครงของฉันมีลักษณะดังนี้:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <android.support.v4.widget.NestedScrollView
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                android:layout_gravity="fill_vertical"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

เค้าโครงนี้ใช้งานไม่ได้ตามที่ตั้งใจไว้ แต่ฉันแก้ไขได้โดยเพียงแค่กำจัดNestedScrollViewและใช้ไฟล์LinearLayout. มันใช้ได้สำหรับฉันทันทีบน Android Support Library v23.1.0 ต่อไปนี้เป็นรูปแบบการจัดวาง:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <LinearLayout
            android:orientation="vertical"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="4dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

PS: นี่เป็นไฟล์เลย์เอาต์สองไฟล์ในโครงการของฉัน ฉันคัดลอกและวางที่นี่และพยายามจัดโครงสร้างให้เหมือนในไฟล์เดียว ขออภัยหากทำพลาดขณะคัดลอกวาง แต่โปรดแจ้งให้เราทราบหากเป็นเช่นนั้นเพื่อที่จะได้แก้ไขได้


1

สิ่งต่อไปนี้ควรตรวจสอบความสูงของเพจเจอร์มุมมองที่เหมาะสม แฟรกเมนต์คือแฟรกเมนต์แรกที่มาจากเพจเจอร์มุมมอง

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <fragment
            class="com.mydomain.MyViewPagerFragment"
            android:id="@+id/myFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

1

ผมมีความปรารถนาเดียวกันรังภายในViewPager NestedScrollViewแต่มันก็ไม่ได้ผลสำหรับฉันเช่นกัน ในกรณีของฉันสิ่งViewPagerนี้อยู่ภายในFragmentดังนั้นฉันจึงสามารถสลับเนื้อหาได้ขึ้นอยู่กับการโต้ตอบกับลิ้นชัก แน่นอนว่า AppBar การยุบและอื่น ๆ จะต้องใช้งานได้

หากผู้ใช้เลื่อนหน้าในเพจเจอร์ในแนวตั้งฉันต้องการให้หน้าอื่น ๆ เลื่อนเหมือนกันเพื่อให้ผู้ใช้แสดงผลโดยรวมที่เพจเจอร์นั้นเลื่อนเอง

สิ่งที่ฉันได้ผลคือฉันไม่ได้ฝังViewPagerภายใน a อีกต่อไปNestedScrollViewแต่ฉันฝังเนื้อหาของชิ้นส่วนที่มีอยู่ภายในไฟล์NestedScrollView.

จากนั้นในกรณีที่มีการเลื่อนในส่วนหนึ่งฉันจะแจ้งให้คอนเทนเนอร์ทราบถึงตำแหน่งการเลื่อนใหม่ซึ่งเก็บไว้

สุดท้ายในการปัดไปทางซ้ายหรือขวาที่ตรวจพบจากเพจเจอร์ (โดยใช้การaddOnPageChangeListenerค้นหาสถานะการลาก) ฉันจะแจ้งชิ้นส่วนทางซ้ายหรือขวาของเป้าหมายซึ่งจะต้องเลื่อน (ขึ้นอยู่กับความรู้เกี่ยวกับคอนเทนเนอร์) เพื่อให้จัดแนวจากส่วนที่ฉันมา


โดยพื้นฐานแล้วคุณเขียนการใช้งาน ViewPager ของคุณเองหรือไม่? คุณสามารถแบ่งปันรหัสนี้ได้หรือไม่?
joseph

ฉันทำบางอย่างที่คล้ายกับสิ่งนี้ (ถ้าฉันเข้าใจถูกต้อง) ซึ่งก็คือการสร้างเลย์เอาต์เชิงเส้นในเลย์เอาต์ผู้ประสานงานของคุณซึ่งมีแท็บเลย์เอาต์ (ถ้าจำเป็น) และช่องมองภาพแทนการเลื่อนแบบซ้อนกัน จากนั้นชิ้นส่วนจะมี scrollview ที่ซ้อนกันเป็นองค์ประกอบรูท สิ่งนี้ใช้ได้ผลสำหรับฉัน แต่ฉันต้องการเพียงแค่มีมุมมองที่ซ้อนกันหนึ่งรายการแทนที่จะทำซ้ำในแต่ละส่วน
คริส

0

ฉันรู้วิธีแก้ปัญหาที่ใช้ได้ผลอย่างหนึ่ง: คุณใช้ Activity กับ CoordinatorLayout และใช้ FrameLayout คอนเทนเนอร์ แล้ว. ใช้ตัวจัดการส่วนเพื่อใส่ส่วนในคอนเทนเนอร์ ตัวอย่างเช่นรหัสของฉัน:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        app:layout_scrollFlags="scroll|enterAlways"
        android:layout_height="@dimen/toolbar_height"
        android:background="?attr/colorPrimary"
        android:gravity="center">

    </android.support.v7.widget.Toolbar>


</android.support.design.widget.AppBarLayout>

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

</FrameLayout>

และ Fragment:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.improvemdia.inmyroom.MainFragment">

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

จากนั้นใช้ FragmentManager

getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MainFragment())
            .commit();

ฉันคิดว่าLinearLayoutเค้าโครงภายใน Fragment ไม่จำเป็นที่นี่ ดูคำตอบของฉันฉันใช้ a LinearLayoutแทนFrameLayoutในเลย์เอาต์กิจกรรมของฉันและรูทของแฟรกเมนต์ของฉันคือ ViewPager (ไม่มีเลย์เอาต์การตัด)
ตะคริว

0

หลังจากใช้เวลาหลายชั่วโมงในการลองทำตามคำแนะนำทั้งหมดข้างต้นในที่สุดฉันก็ทำได้ กุญแจสำคัญคือการใส่NestedScrollViewเข้าไปข้างในPageViewerและตั้งค่าlayout_behaviorเป็น'@string/appbar_scrolling_view_behavior'สำหรับทั้งสองมุมมอง เค้าโครงสุดท้ายเป็นอย่างไร

<CoordinatorLayout>
    <ViewPager app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <NestedScrollView fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <Content>...</Content>
        </NestedScrollView>
    </ViewPager>
    <AppBarLayout>...</AppBarLayout>
</CoordinatorLayout>

0

คุณเพิ่งลบNestedScrollViewบน xml ของคุณและเพิ่มรหัสนี้ในชั้นเรียนของคุณ

yourGridView.setNestedScrollingEnabled(true);


0

จริงๆแล้ว NestedScrollView ไม่จำเป็นต้องเป็นพี่น้องโดยตรงของ CollapsingToolbarLayout ใน CoordinatorLayout ฉันประสบความสำเร็จในบางสิ่งบางอย่างที่เป็นจริง appbar_scrolling_view_behavior ทำงานใน 2 ส่วนที่ซ้อนกัน

รูปแบบกิจกรรมของฉัน:

<android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout>

            <android.support.design.widget.CollapsingToolbarLayout>

                <include
                    layout="@layout/toolbar"/>

            </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/container"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</android.support.design.widget.CoordinatorLayout>

ในกรอบ "คอนเทนเนอร์" เค้าโครงฉันได้ขยายส่วนนี้:

<android.support.constraint.ConstraintLayout>

    ... some content ...

    <android.support.v4.view.ViewPager/>

    ...

</android.support.constraint.ConstraintLayout>

และชิ้นส่วนภายใน ViewPager นั้นมีลักษณะดังนี้:

<RelativeLayout>

    <android.support.v7.widget.RecyclerView/>

    ....

</RelativeLayout>

ความจริงที่ว่า NestedScrollView สามารถอยู่ลึกลงไปในลำดับชั้นของ CoordinatorLayout ลูก ๆ และพฤติกรรมการเลื่อนได้ทำให้ฉันประหลาดใจ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.