浮动按钮旋转取决于 View Pager 滚动状态
Floating Button rotation depending on View Pager scroll state
我正在开发一个 Android 应用程序,我想实现一个功能,但由于缺乏经验,我不知道该怎么做,不幸的是谷歌搜索没有帮助。
所以,有一个带有两个选项卡的 ViewPager 和一个带有箭头图像的 FloatingActionButton,我想做的是旋转箭头取决于寻呼机的滚动状态(在第一个选项卡上它应该是一个左箭头,然后在选项卡之间它应该平滑地旋转以面向上或向下(并不重要),最后在第二个选项卡上它应该成为右箭头,反之亦然)。
我一直在尝试 RotateAnimation class,但没成功。
请注意我的应用程序的 minSdkVersion 是 14 (Jelly Bean +),所以 Vector drawables 和其他 just-Lollipop 甚至 KitKat 东西都不适合我。
提前致谢。
您需要在查看寻呼机上使用 PageChangedListener
。然后听onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
会告诉你计算旋转角度需要什么
请注意,这不是动画——您将根据 viewpager 的滚动明确设置按钮的旋转。您需要跟踪当前页面并将其与您在 onPageScrolled
的位置参数中获得的页面进行比较。为此,您可以使用我的代码作为示例:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (currentPagePosition != position && (int) positionOffset == 0 && positionOffsetPixels == 0) {
// New page is set!
currentPagePosition = position;
onNewPage(currentPagePosition);
} else {
if (positionOffset == 0 && positionOffsetPixels == 0) {
// User scrolled a little, then let go
// and it went back without changing position
onNewPage(position);
return;
}
if (position == currentPagePosition) {
onPageScrolledToLeft(position, positionOffset);
} else if (position < currentPagePosition) {
onPageScrolledToRight(position, positionOffset);
}
}
}
有了这个,现在你可以实现这两个方法来使用positionOffset来计算旋转角度了。注意 onPageScrolledToLeft
表示当前页面向左移动,或者用户向右滚动。发生这种情况时,positionOffset
的值将从 1.0 变为 0.0。当 onPageScrolledToRight
触发时,positionOffset
将从 0.0 - 1.0 变化。现在在计算出适当的旋转(即 0.5 可能应该是 0 度)之后,您可以使用视图的 setRotation(float rot)
方法。
您正在使用的库在其视图中包含阴影,这意味着在使用 setRotation
时它会与视图的其余部分一起旋转。您可以通过将 Floating Action Button 包装在 FrameLayout 中来解决这个问题,从 FAB 中删除 fab_icon
属性,然后在 FAB 顶部添加一个 ImageView,如下所示:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp">
<com.getbase.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:fab_colorNormal="?attr/colorAccent"
app:fab_colorPressed="?attr/colorAccentHighlight"/>
<ImageView
android:id="@+id/fab_icon_overlay"
android:layout_width="@dimen/fab_icon_size"
android:layout_height="@dimen/fab_icon_size"
android:layout_gravity="center"
android:layout_marginTop="-3dp"
android:src="@drawable/ic_content_add"
android:tint="@android:color/white"/>
</FrameLayout>
然后,不是旋转 FAB,而是旋转 ImageView。结果是 FAB 似乎在旋转,因为它是一个圆圈,而且它里面的图标在旋转。请注意 android:layout_marginTop
的值必须是 fab_shadow_offset
的负值才能使图标完美居中。默认值为 3dp。
你现在要做的是将 Ashtons 的回答与对 setRotation(float rotation)
的调用结合起来,请注意旋转是以度为单位的 (0.0f
- 360.0f
)。
解决方案可能如下所示:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// positionOffset ranges from 0.0f to 1.0f, multiply it by 180.0f to rotate the
// icon clockwise, making the icon appear flipped when scrolled to the last page.
// Multiply by -180.0f to rotate counter-clockwise.
fabIconOverlay.setRotation(positionOffset * 180.0f);
}
我正在开发一个 Android 应用程序,我想实现一个功能,但由于缺乏经验,我不知道该怎么做,不幸的是谷歌搜索没有帮助。
所以,有一个带有两个选项卡的 ViewPager 和一个带有箭头图像的 FloatingActionButton,我想做的是旋转箭头取决于寻呼机的滚动状态(在第一个选项卡上它应该是一个左箭头,然后在选项卡之间它应该平滑地旋转以面向上或向下(并不重要),最后在第二个选项卡上它应该成为右箭头,反之亦然)。
我一直在尝试 RotateAnimation class,但没成功。
请注意我的应用程序的 minSdkVersion 是 14 (Jelly Bean +),所以 Vector drawables 和其他 just-Lollipop 甚至 KitKat 东西都不适合我。
提前致谢。
您需要在查看寻呼机上使用 PageChangedListener
。然后听onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
会告诉你计算旋转角度需要什么
请注意,这不是动画——您将根据 viewpager 的滚动明确设置按钮的旋转。您需要跟踪当前页面并将其与您在 onPageScrolled
的位置参数中获得的页面进行比较。为此,您可以使用我的代码作为示例:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (currentPagePosition != position && (int) positionOffset == 0 && positionOffsetPixels == 0) {
// New page is set!
currentPagePosition = position;
onNewPage(currentPagePosition);
} else {
if (positionOffset == 0 && positionOffsetPixels == 0) {
// User scrolled a little, then let go
// and it went back without changing position
onNewPage(position);
return;
}
if (position == currentPagePosition) {
onPageScrolledToLeft(position, positionOffset);
} else if (position < currentPagePosition) {
onPageScrolledToRight(position, positionOffset);
}
}
}
有了这个,现在你可以实现这两个方法来使用positionOffset来计算旋转角度了。注意 onPageScrolledToLeft
表示当前页面向左移动,或者用户向右滚动。发生这种情况时,positionOffset
的值将从 1.0 变为 0.0。当 onPageScrolledToRight
触发时,positionOffset
将从 0.0 - 1.0 变化。现在在计算出适当的旋转(即 0.5 可能应该是 0 度)之后,您可以使用视图的 setRotation(float rot)
方法。
您正在使用的库在其视图中包含阴影,这意味着在使用 setRotation
时它会与视图的其余部分一起旋转。您可以通过将 Floating Action Button 包装在 FrameLayout 中来解决这个问题,从 FAB 中删除 fab_icon
属性,然后在 FAB 顶部添加一个 ImageView,如下所示:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp">
<com.getbase.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:fab_colorNormal="?attr/colorAccent"
app:fab_colorPressed="?attr/colorAccentHighlight"/>
<ImageView
android:id="@+id/fab_icon_overlay"
android:layout_width="@dimen/fab_icon_size"
android:layout_height="@dimen/fab_icon_size"
android:layout_gravity="center"
android:layout_marginTop="-3dp"
android:src="@drawable/ic_content_add"
android:tint="@android:color/white"/>
</FrameLayout>
然后,不是旋转 FAB,而是旋转 ImageView。结果是 FAB 似乎在旋转,因为它是一个圆圈,而且它里面的图标在旋转。请注意 android:layout_marginTop
的值必须是 fab_shadow_offset
的负值才能使图标完美居中。默认值为 3dp。
你现在要做的是将 Ashtons 的回答与对 setRotation(float rotation)
的调用结合起来,请注意旋转是以度为单位的 (0.0f
- 360.0f
)。
解决方案可能如下所示:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// positionOffset ranges from 0.0f to 1.0f, multiply it by 180.0f to rotate the
// icon clockwise, making the icon appear flipped when scrolled to the last page.
// Multiply by -180.0f to rotate counter-clockwise.
fabIconOverlay.setRotation(positionOffset * 180.0f);
}