Просмотр с ViewPager без прокрутки по вертикали в ScrollView

Это похоже на ежу понятно, но почему-то я застрял. Представление не позволит мне прокручивать его. Как будто высота фрагмента, надутого в ViewPager, не рассчитывается. Поиск SO предполагает, что мне нужно написать свой собственный ViewPager и переопределить onMeasure(), но я не могу поверить, что мне придется зайти так далеко для чего-то такого простого, как это.

Вот мой макет, несколько упрощенный для удобства. ViewPager заполнен фрагментами, занимающими пространство далеко за пределами экрана (по вертикали). Тем не менее, ничего на экране не прокручивается. Почему это?

<ScrollView
    android:id="@+id/scroll_view"
    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:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/header_image_view"
            android:layout_width="0dp"
            android:layout_height="170dp"
            app:layout_constraintTop_toTopOf="parent"/>

        <TextView
            android:id="@+id/title_text_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/header_image_view"/>

        <Button
            android:id="@+id/resume_training_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/title_text_view"/>

        <android.support.design.widget.TabLayout
            android:id="@+id/lesson_table_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"          
            app:layout_constraintTop_toBottomOf="@id/resume_training_button">
        </android.support.design.widget.TabLayout>

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/lesson_table_layout">
        </android.support.v4.view.ViewPager>
    </android.support.constraint.ConstraintLayout>
</ScrollView>

Вот пример просмотра. Текст Lorem ipsum продолжается долго, и я ожидаю, что весь экран будет прокручиваться, но это не так.

пример_просмотр

Заранее спасибо!


comment
просто для уточнения, вы пробовали какой-либо другой макет ?? как линейный или относительный внутри прокрутки??   -  person Santanu Sur    schedule 28.02.2018
comment
@SantanuSur да, я пробовал их оба. Тот же результат. Но спасибо за мысль. Я также обновил вопрос с изображением, чтобы прояснить мою проблему.   -  person Algar    schedule 01.03.2018
comment
но что вы делаете белое пустое пространство в верхней части окна просмотра.. вы можете использовать его..   -  person Santanu Sur    schedule 01.03.2018
comment
Там должно быть изображение.   -  person Algar    schedule 01.03.2018
comment
сделайте одну вещь.. замените scrollView на nestedScrollView.. и поместите вокруг него линейный макет.. я пишу решение..   -  person Santanu Sur    schedule 01.03.2018


Ответы (3)


Есть такая проблема, иногда ScrollView и ViewPager переключают фокус. Если у вас есть ViewPager в ScrollView, и вы хотите, чтобы он всегда оставался в фокусе, когда вы касаетесь его, а ScrollView никогда не получает фокус, установка requestDisallowInterceptTouchEvent сделает это.

 mViewPager= (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(adapter);
    mViewPager.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mViewPager.getParent().requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });

Найдите дополнительные ответы в этой ветке

РЕДАКТИРОВАТЬ:

Еще один способ, который, как я вижу, может работать, - это программно настроить прокрутку на ваш вкладку, как это

tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
person Rainmaker    schedule 28.02.2018
comment
Спасибо за ваш ответ, но это не помогает. Ничего не прокручивается по вертикали (хотя ViewPager работает по горизонтали). Я также обновил вопрос изображением, чтобы прояснить представление. - person Algar; 01.03.2018
comment
Отредактировал мой ответ, я должен попробовать это. Если это не сработает, попробуйте сделать текстовое представление внутри фрагмента (где у вас есть текст на картинке) прокручиваемым, и это будет для вас обходным путем. - person Rainmaker; 01.03.2018

В итоге я его немного переписал. Не было смысла прокручивать выше TabLayout, поэтому в итоге я использовал CoordinatorLayout, согласно

<CoordinatorLayout>        <-- width/height = match_parent
    <AppBarLayout>         <-- width = match_parent, height = wrap_content
        <ImageView/>
        <TextView/>
        <Button/>
        <TabLayout/>
    <AppBarLayout/>
    <ViewPager/>           <-- width/height = match_parent, app:layout_behavior="@string/appbar_scrolling_view_behavior"
<CoordinatorLayout/>

И каждый фрагмент, вставленный в ViewPager, теперь завернут в NestedScrollView.

Спасибо за другие ответы. Возможно, это поможет кому-то еще!

person Algar    schedule 01.03.2018
comment
Гениальное решение! Кстати, чтобы сделать весь контент прокручиваемым (например, ScrollView), добавьте CollapsingToolbarLayout и установите его app:layout_scrollFlags="scroll". - person Dewey Reed; 26.07.2019

Попробуйте вложенныйScrollView вместо scrollView.. попробуйте следующий фрагмент..

<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="match_parent"
        android:layout_height="match_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...
     
     <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/lesson_table_layout">
    </android.support.v4.view.ViewPager>
   
     </LinearLayout>
</android.support.v4.widget.NestedScrollView>

person Santanu Sur    schedule 01.03.2018
comment
Спасибо, но не повезло. И я пробовал все варианты этого раньше. Я склонен думать, что это вина onMeasure, а не реальной иерархии представлений. - person Algar; 01.03.2018