вложенные видовые пейджеры: позволяя внешнему перелистывать, но не внутреннему - PullRequest
0 голосов
/ 28 февраля 2019

В двух словах:

У меня есть ViewPager, vpOuter, который отображает фрагмент с другим ViewPager, vpInner.

Предполагается, что пользователь может перемещаться между фрагментами vpOuter, но фрагменты, отображаемые с помощью vpInner, можно поменять местами только программно.

Прямо сейчас, нажатие vpInner ничего не делает, а перемещение снаружи vpInner переключается между фрагментами vpOuter.

Как сделать так, чтобы считывание vpInner распознавалось как пролистывание между vpOuter?

(двумя ViewPagerони не знают друг друга)

Полная история:

Хорошо, у меня есть действие, в котором есть пейджер с тремя фрагментами.

Давайте назовем их A, B и C.

Теперь пользователь может перемещаться между ними или использовать нижнюю навигацию.

A - это наш "фрагмент просмотра", и он отображает что-то, еслиесть что отображать или ничего, если нечего отображать, но он будет отображать только одинВ то же время.

A содержит пейджер без возможности просмотра.

Причина заключается в том, что мы хотим отображать текст и изображения, а кто-что-что знает, и мы создаемфрагмент просмотра для каждого типа мультимедиа, который мы хотим отобразить.Поэтому, когда нам нужно что-то отобразить, мы проверяем, что это такое, переключаемся на соответствующий фрагмент и заполняем его данными.

В результате A будет выглядеть примерно так:

<?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:orientation="vertical">


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

        <[...].android.ui.widgets.NonswipableViewPager
            android:id="@+id/view_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

    <!--irrrelevant floating action button here-->

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

где

/**A view pager that disables swiping to switch between pages.
 * Switching must happen programmatically.*/
class NonswipableViewPager:ViewPager{
    constructor(context:Context):super(context)
    constructor(context: Context,attributeSet: AttributeSet):super(context,attributeSet)

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return false
    }

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return false
    }
}

Давайте на мгновение представим, что есть только текстовое содержимое, которое мы хотим отобразить.

Тогда у нас есть два фрагмента:

class NoContentView : AbstractContentView() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val fragmentView = inflater.inflate(R.layout.fragment_A_component_text_view, container, false)
        fragmentView.content.text = Html.fromHtml(getString(R.string.A_nothingToShow))
        return fragmentView
    }

    //more irrelevant stuff here
}

который мы показываем, когда нам нечего показать, и

class TextContentView:AbstractContentView(){
    @Volatile private var displayedData:String? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_A_component_text_view, container, false)
        displayedData?.let { view.content.text = it }
        return view
    }

    override fun display(c: IDisplayableContent) {
        displayedData = String(c.data, Charsets.UTF_8)
        content?.text = displayedData
    }
}

, и они оба раздувают этот макет здесь:

<?xml version="1.0" encoding="utf-8"?>
<android.widget.LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:layout_gravity="center"
        android:fillViewport="true"
        >
        <TextView
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            android:gravity="center"
            tools:text="PLACEHOLDER" />
    </ScrollView>
</android.widget.LinearLayout>

Если отображается TextContentView, все работает нормальнои я могу без проблем пролистывать фрагменты A, B и C.

Однако, когда отображается NoContentView, мне нужно прилагать сознательные усилия, чтобы избежать текстового содержимого, когдасмахивание, иначе он просто ничего не будет делать.

Как я могу заставить его всегда вести себя так, как будто там просто нет пейджера с невидимым просмотром?

1 Ответ

0 голосов
/ 05 марта 2019

Проблема здесь вызвана тем, что внешний ViewPager чувствует, что имеет прокручиваемый контент, который может прокручиваться в том же направлении, поэтому внешний ViewPager отказывается прокручивать в этом направлении.

Это может быть решено путем переопределения canScrollHorizontally(int direction) во внутреннем ViewPager для возврата false.

...