Использование BottomSheetBehavior с внутренним CoordinatorLayout



библиотека поддержки проектирования v. 23.2 ввел BottomSheetBehavior, что позволяет детям координатора выступать в качестве нижних листов (представления перетаскиваются из нижней части экрана).



то, что я хотел бы сделать, это иметь,как вид нижнего листа, следующий вид (типичный координатор + сворачивание материала):



<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>

<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>

<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>

</CoordinatorLayout>


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



Я уверен, что это может быть обработано путем подклассов CoordinatorLayout, или даже лучше на подклассы BottomSheetBehavior. У вас есть какие-нибудь намеки?



мысли





  • requestDisallowInterceptTouchEvent() должен использоваться, чтобы украсть события от родителя в некоторых условия:




    • когда AppBarLayout смещение > 0

    • когда AppBarLayout смещение == 0, но мы прокрутки вверх (подумайте об этом на секунду и вы увидите)



  • первое условие можно получить, установив OnOffsetChanged во внутреннюю панель приложения;



  • второй требует некоторой обработки событий, например:



    switch (MotionEventCompat.getActionMasked(event)) {
    case MotionEvent.ACTION_DOWN:
    startY = event.getY();
    lastY = startY;
    userIsScrollingUp = false;
    break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
    userIsScrollingUp = false;
    break;
    case MotionEvent.ACTION_MOVE:
    lastY = event.getY();
    float yDeltaTotal = startY - lastY;
    if (yDeltaTotal > touchSlop) { // Moving the finger up.
    userIsScrollingUp = true;
    }
    break;
    }



вопросы



излишне Слушай, я не могу сейчас это сделать. Я не могу поймать события, когда условия выполнены, и не поймать их в других случаях. На изображении ниже вы можете увидеть, что происходит со стандартным CoordinatorLayout:




  • лист отклоняется при прокрутке вниз на панели приложений, но не при прокрутке вниз на вложенное содержимое. Кажется, что вложенные события прокрутки не распространяются на поведение координатора;


  • существует также проблема с внутренней панелью приложений: вложенное содержимое прокрутки не следует за панелью приложений, когда она сворачивается..



enter image description here



я установил a пример проекта на github что показывает эти проблемы.



просто чтобы быть ясным, желаемое поведение:




  • правильное поведение панелей приложений / видов прокрутки внутри листа;


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


  • когда лист свернут, прокрутка вверх жесты будут расширять его (без эффекта на внутренней панели приложений).



пример из приложения Контакты (который, вероятно, не использует BottomSheetBehavior, но это то, что я хочу):



enter image description here

644   6  

6 ответов:

Я наконец-то выпустил свою реализацию. Найди его на Github или непосредственно из jcenter:

compile 'com.otaliastudios:bottomsheetcoordinatorlayout:1.0.0’

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

Я использую это в течение длительного времени, и он не должен иметь проблем прокрутки, поддерживает перетаскивание на ABL и т. д.

Я просто следил за тем, как вы задали вышеуказанный вопрос, и придумал решение, которое может потребовать больше объяснений.Пожалуйста, следуйте примеру кода и интегрировать дополнительную часть в xml, чтобы сделать его вести себя как BottomSheeet поведение

<CoordinatorLayout>
   <AppBarLayout>
        <Toolbar
            app:layout_collapseMode="pin">
        </Toolbar>
    </AppBarLayout>
    <NestedScrollView
         app:layout_behavior=“@string/bottom_sheet_behavior” >
        <include layout="@layout/items" />
    </NestedScrollView>

    <!-- Bottom Sheet -->

     <BottomSheetCoordinatorLayout>
        <AppBarLayout
            <CollapsingToolbarLayout">
             <ImageView />
                <Toolbar />
            </CollapsingToolbarLayout>
        </AppBarLayout>
        <NestedScrollView">
            <include layout="@layout/items" />
        </NestedScrollView>
    </BottomSheetCoordinatorLayout>
</CoordinatorLayout>

Примечание : решение, которое работало для меня, уже объяснено в последнем комментарии вашего вопроса

лучше explantion : https://github.com/laenger/BottomSheetCoordinatorLayout

Если первый ребенок nestedscroll это будет происходить некоторые другие проблемы. Это решение исправлено моя проблема я надеюсь также исправить вашу.

<CoordinatorLayout
    app:layout_behavior=“@string/bottom_sheet_behavior”>

   <AppBarLayout>
        <CollapsingToolbarLayout>
           <ImageView />
        </CollapsingToolbarLayout>
    </AppBarLayout>
</LinearLayout>
    <NestedScrollView>
        <LinearLayout>
            < Content ... />
        </LinearLayout>
    </NestedScrollView>
</LinearLayout>
</CoordinatorLayout>

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

попробуйте следующее:

<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>

<AppBarLayout>
    <CollapsingToolbarLayout>
       <ImageView />
    </CollapsingToolbarLayout>
</AppBarLayout>

<LinearLayout>
     <!--don't forget to addd this line-->
     app:layout_behavior="@string/appbar_scrolling_view_behavior">

        < Content ... />
</LinearLayout>

Я следил за первоначальным тестовым проектом GitHub laenger по этой проблеме, и я рад поделиться с вами решением для некоторых из его проблем, так как мне тоже нужно было это поведение в моем приложении.

это решение его вопроса : панель инструментов иногда рушится слишком рано

чтобы предотвратить это, вам нужно создать свой собственный AppBarLayout.Behavior, так как это когда вы прокручиваете вверх, все еще перетаскивая, что AppBarLayout.behavior получает движение прокрутки. Нам нужно определить, если его в STATE_DRAGGING и просто вернитесь, чтобы избежать преждевременного скрытия / сворачивания панели инструментов.

public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {

    private CoordinatorLayoutBottomSheetBehavior behavior;

    public CustomAppBarLayoutBehavior() {
    }

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
        behavior = CoordinatorLayoutBottomSheetBehavior.from(parent);
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
        if(behavior.getState() == CoordinatorLayoutBottomSheetBehavior.STATE_DRAGGING){
            return;
        }else {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        }
    }

    @Override
    public void setDragCallback(@Nullable DragCallback callback) {
        super.setDragCallback(callback);
    }
}

это может быть хорошим началом, как мы решаем другие вопросы:

панель инструментов не может быть свернута через перетаскивания

главный координатор макет потребляет некоторую прокрутку

Я на самом деле не хороший пользователь/анимационный человек, но hardwork иногда окупается пониманием кода, находя правильную функцию обратного вызова/переопределения для реализации.

как поведение appbarlayout

<android.support.design.widget.AppBarLayout
    android:id="@+id/bottom_sheet_appbar"
    style="@style/BottomSheetAppBarStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="your.package.CustomAppBarLayoutBehavior">

макет для полного экрана макета appbar выглядит следующим образом: -

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/detail_backdrop_height"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

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

        <ImageView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax" />

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

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

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

<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="vertical"
        android:paddingTop="24dp">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/card_margin">

            <LinearLayout
                style="@style/Widget.CardContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Info"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/cheese_ipsum" />

            </LinearLayout>

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

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/card_margin"
            android:layout_marginLeft="@dimen/card_margin"
            android:layout_marginRight="@dimen/card_margin">

            <LinearLayout
                style="@style/Widget.CardContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Friends"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/cheese_ipsum" />

            </LinearLayout>

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

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/card_margin"
            android:layout_marginLeft="@dimen/card_margin"
            android:layout_marginRight="@dimen/card_margin">

            <LinearLayout
                style="@style/Widget.CardContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Related"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/cheese_ipsum" />

            </LinearLayout>

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

    </LinearLayout>

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

<android.support.design.widget.FloatingActionButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    app:layout_anchor="@id/appbar"
    app:layout_anchorGravity="bottom|right|end"
    android:src="@drawable/ic_discuss"
    android:layout_margin="@dimen/fab_margin"
    android:clickable="true"/>

и после этого вы должны реализовать AppBarLayout.OnOffsetChangedListener в вашем классе и установить смещение экрана.

Comments

    Ничего не найдено.