使用动画和fragment改善Android表单

时间:2021-03-16 23:20:04

下图是captain train的搜索页面的效果图,这篇文章我就来分析一下如何实现一个类似的效果。

使用动画和fragment改善Android表单

分析Android中的动画效果,最好是从一个放慢的动画效果图来分析,可以通过Android系统中的开发者选项里面设置动画的时长。下图是10倍动画时长的效果

使用动画和fragment改善Android表单

整个界面主要由两部分构成,正常模式显示的表单以及当某一个表单获取焦点的时候,需要显示出来的编辑面板(比如点击日期表单的时候,含有日期控件的编辑面板会显示出来),编辑面板可以使用fragment,这样也便于代码的模块化。
仔细观察,可以发现整个效果其实是由多个同时发生的子动画组成的。子动画主要有一下几个:
1.移动获取焦点的控件,以及这个控件上面的所有控件,最终的结果就是获取焦点的控件移动到actionbar下面。
2.获取焦点的控件下面的控件的淡出效果。主要就是隐藏在编辑模式下不需要的控件。
3.编辑面板(比如日期控件)的渐入效果。
4.附着(stick to)动画,主要是一些控件需要始终位于获取焦点的控件下方,这些控件会随着获取焦点的控件一起移动。
下面就是每个动画对应的代码实现:
layout很简单,主要容器就是一个scrollview,具体代码可以参考github代码。

1. 移动获取焦点的控件
如果获取焦点的控件是容器的直接子控件,通过getTop()方法就可以得到需要移动的距离,如果不是的话,就需要使用View#getDrawingRect(Rect)和容器的ViewGroup#offsetDescendantRectToMyCoords(View, Rect)方法。

private final Rect mTmpRect = new Rect();

private void focusOn(View v, View movableView, boolean animated) {

v.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(v, mTmpRect);

movableView.animate().
translationY(-mTmpRect.top).
setDuration(animated ? ANIMATION_DURATION : 0).
setInterpolator(ANIMATION_INTERPOLATOR).
start();
}

2.获取焦点的控件下的控件的淡出效果
控件会在向下移动容器高度的一半后完全淡出。这里要通过容器的OnLayoutChangeListener来获取容器的高度。

private void fadeOutToBottom(View v, boolean animated) {
v.animate().
translationYBy(mHalfHeight).
alpha(0).
setDuration(animated ? ANIMATION_DURATION : 0).
setInterpolator(ANIMATION_INTERPOLATOR).
start();
}

3.编辑面板(比如日期控件)的渐入效果
编辑模式要现实的控件会放到一个容器中,这个容器默认是不可见的,进入编辑模式之后,设置容器可见,并且将容器的y坐标设置为0。为了避免遮挡住获取焦点的控件,可以给容器设置一个比较大的padding。
private void slideInToTop(View v, boolean animated) {
v.animate().
translationY(0).
alpha(1).
setDuration(animated ? ANIMATION_DURATION : 0).
setInterpolator(ANIMATION_INTERPOLATOR);
}

4.附着动画
这里就是让一个灰色的view始终保持在获取焦点的控件下面。

private void stickTo(View v, View viewToStickTo, boolean animated) {

v.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(v, mTmpRect);

v.animate().
translationY(viewToStickTo.getHeight() - mTmpRect.top).
setDuration(animated ? ANIMATION_DURATION : 0).
setInterpolator(ANIMATION_INTERPOLATOR).
start();
}

github地址


参考:
http://cyrilmottier.com/2014/05/20/custom-animations-with-fragments/

https://git.mika-dev.com/public