Как сделать привязку панели инструментов в представлении или вне поля зрения при использовании библиотеки дизайна Google?
Я пытаюсь добиться такого эффекта, как WhatsApp, где панель инструментов (при прокрутке) будет зажиматься в виде магнита или вне поля зрения магнита.
Что у меня есть в моем MainActivity XML:
- DrawerLayout - базовый макет
- CoordinatorLayout - макет для панели приложений и панели инструментов и вкладок
- AppBarLayout - для размещения панели инструментов и вкладок
- Панель инструментов - имеет ЭТО флаг:
app:layout_scrollFlags="scroll|enterAlways"
- SlidingTabLayout - отображает вкладки
- ViewPager - для вкладок
- RecyclerView - для Coordinatorlayout
Теперь не поймите меня неправильно, это работает, когда я прокручиваю вниз панель инструментов, выталкивается из поля зрения, но говорю, что я прекращаю прокрутку на полпути, тогда панель инструментов просто сидит там наполовину скрытая вне поля зрения, а другая половина в поле зрения.
Как я могу подойти к решению этой проблемы, так как я хочу, чтобы она либо выходила из вида, либо просматривалась.
Ответы
Ответ 1
Эта функция была добавлена в версию поддержки библиотеки поддержки Android 23.1.0
.
Из примечаний к выпуску:
Добавлена поддержка привязки края к классу AppBarLayout, добавив Постоянная константа SCROLL_FLAG_SNAP. Когда прокрутка заканчивается, если только просмотр частично видимый, вид защелкивается и прокручивается до ближайшего края.
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap" />
-----
-----
За дополнительной информацией: http://android-developers.blogspot.in/2015/10/android-support-library-231.html
EDIT: добавлена конечная цитата в layout_scrollFlags, чтобы сделать это синтаксически правильным
Ответ 2
EDIT: с поддержкой 23.1.0 это больше не требуется. См. этот ответ.
Один из возможных способов решения этой проблемы - настроить Behavior
на AppBarLayout
.
<android.support.design.widget.AppBarLayout
app:layout_behavior="com.myapp.AppBarLayoutSnapBehavior"
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
Ваш AppBarLayoutSnapBehavior
изменит поведение по умолчанию AppBarLayout.Behavior
, добавив логику привязки при остановке прокрутки.
Надеемся, что приведенный ниже код является самоочевидным.
package com.myapp;
public class AppBarLayoutSnapBehavior extends AppBarLayout.Behavior {
private ValueAnimator mAnimator;
private boolean mNestedScrollStarted = false;
public AppBarLayoutSnapBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View directTargetChild, View target, int nestedScrollAxes) {
mNestedScrollStarted = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
if (mNestedScrollStarted && mAnimator != null) {
mAnimator.cancel();
}
return mNestedScrollStarted;
}
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
if (!mNestedScrollStarted) {
return;
}
mNestedScrollStarted = false;
int scrollRange = child.getTotalScrollRange();
int topOffset = getTopAndBottomOffset();
if (topOffset <= -scrollRange || topOffset >= 0) {
// Already fully visible or fully invisible
return;
}
if (topOffset < -(scrollRange / 2f)) {
// Snap up (to fully invisible)
animateOffsetTo(-scrollRange);
} else {
// Snap down (to fully visible)
animateOffsetTo(0);
}
}
private void animateOffsetTo(int offset) {
if (mAnimator == null) {
mAnimator = new ValueAnimator();
mAnimator.setInterpolator(new DecelerateInterpolator());
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setTopAndBottomOffset((int) animation.getAnimatedValue());
}
});
} else {
mAnimator.cancel();
}
mAnimator.setIntValues(getTopAndBottomOffset(), offset);
mAnimator.start();
}
}
Единственное, что выглядит прокрутка (в моем случае a RecyclerView
), а также Toolbar
. Мне это действительно нравится, но я не уверен, что вы хотите.
Ответ 3
Я просто скрыл макет панели действий в основном действии и задал интервал для CollapsingToolbarLayout.
он работает для меня.
в основной деятельности
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().hide();
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Name");
loadBackdrop();
и layout_activity_main
<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|snap"
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>