Android 滚动时折叠布局
Collapsing layout during scrolling in Android
我希望自定义视图在滚动过程中通过过渡折叠。
我有 AppBarLayout
,里面有一个 Toolbar
。在其下方有一个我想要折叠的自定义视图。
自定义视图下方有一个 NestedScrollView
和 LinearLayout
。
工具栏为绿色,自定义布局为粉红色,线性滚动条为灰色:
向下滚动后:
<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/appbar"
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="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_marginTop="?attr/actionBarSize"
android:background="@drawable/background"
android:gravity="center">
</RelativeLayout>
<ScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="170dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
layout="@layout/linear"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</android.support.design.widget.CoordinatorLayout>
我应该使用自定义行为和 CoordinatorLayout
还是使用带有翻译动画的 NestedScroll
进行翻译?
使用 Observable ScrollView 库
https://github.com/ksoichiro/Android-ObservableScrollView
我在没有任何图书馆的情况下设法做到了这一点。关键是要有两个应用栏布局 - 一个带有占位符和隐藏在自定义视图下的折叠工具栏布局,第二个是普通布局。
然后我创建了两种行为 - 一种用于更改嵌套布局高度,第二种用于在自定义视图内操作内部视图。
这是我的布局:
<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:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<View
android:id="@+id/vieItemDetailsPlaceholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.AppBarLayout
android:id="@+id/second_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/second_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/detailContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.detail.view.Det ailScrollBehavior">
<include
layout="@layout/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" />
</android.support.v4.widget.NestedScrollView>
<!-- second layout with behavior -->
<include layout="@layout/two_circles_layout" />
</android.support.design.widget.CoordinatorLayout>
详细滚动行为:
public class DetailScrollBehavior extends Behavior<NestedScrollView> {
private final Context context;
public DetailScrollBehavior(Context context, AttributeSet attrs) {
this.context = context;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, NestedScrollView child, View dependency) {
return dependency.getId() != R.id.ablItemDetailsSecondToolbar && dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, NestedScrollView child, View dependency) {
int minHeight = context.getResources().getDimensionPixelSize(R.dimen.some_min_height);
int placeholderHeight = getPlaceholderHeight(dependency);
int actionBarHeight = getActionBarHeight(context.getTheme());
if (placeholderHeight < minHeight + actionBarHeight) {
placeholderHeight = minHeight + actionBarHeight;
}
child.setPadding(0, placeholderHeight, 0, 0);
return true;
}
}
和two_circles_layout
的一部分:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/relDetailsContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/team_vs_details_height"
android:layout_marginTop="?attr/actionBarSize"
android:background="@drawable/background"
android:gravity="center"
app:layout_behavior="com.example.DetailBehavior"
tools:showIn="@layout/activity_item_detail">
[ ... ]
</RelativeLayout>
我希望自定义视图在滚动过程中通过过渡折叠。
我有 AppBarLayout
,里面有一个 Toolbar
。在其下方有一个我想要折叠的自定义视图。
自定义视图下方有一个 NestedScrollView
和 LinearLayout
。
工具栏为绿色,自定义布局为粉红色,线性滚动条为灰色:
向下滚动后:
<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/appbar"
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="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_marginTop="?attr/actionBarSize"
android:background="@drawable/background"
android:gravity="center">
</RelativeLayout>
<ScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="170dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
layout="@layout/linear"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</android.support.design.widget.CoordinatorLayout>
我应该使用自定义行为和 CoordinatorLayout
还是使用带有翻译动画的 NestedScroll
进行翻译?
使用 Observable ScrollView 库 https://github.com/ksoichiro/Android-ObservableScrollView
我在没有任何图书馆的情况下设法做到了这一点。关键是要有两个应用栏布局 - 一个带有占位符和隐藏在自定义视图下的折叠工具栏布局,第二个是普通布局。
然后我创建了两种行为 - 一种用于更改嵌套布局高度,第二种用于在自定义视图内操作内部视图。
这是我的布局:
<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:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<View
android:id="@+id/vieItemDetailsPlaceholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.AppBarLayout
android:id="@+id/second_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/second_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/detailContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.detail.view.Det ailScrollBehavior">
<include
layout="@layout/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" />
</android.support.v4.widget.NestedScrollView>
<!-- second layout with behavior -->
<include layout="@layout/two_circles_layout" />
</android.support.design.widget.CoordinatorLayout>
详细滚动行为:
public class DetailScrollBehavior extends Behavior<NestedScrollView> {
private final Context context;
public DetailScrollBehavior(Context context, AttributeSet attrs) {
this.context = context;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, NestedScrollView child, View dependency) {
return dependency.getId() != R.id.ablItemDetailsSecondToolbar && dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, NestedScrollView child, View dependency) {
int minHeight = context.getResources().getDimensionPixelSize(R.dimen.some_min_height);
int placeholderHeight = getPlaceholderHeight(dependency);
int actionBarHeight = getActionBarHeight(context.getTheme());
if (placeholderHeight < minHeight + actionBarHeight) {
placeholderHeight = minHeight + actionBarHeight;
}
child.setPadding(0, placeholderHeight, 0, 0);
return true;
}
}
和two_circles_layout
的一部分:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/relDetailsContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/team_vs_details_height"
android:layout_marginTop="?attr/actionBarSize"
android:background="@drawable/background"
android:gravity="center"
app:layout_behavior="com.example.DetailBehavior"
tools:showIn="@layout/activity_item_detail">
[ ... ]
</RelativeLayout>