华为P8日历的截图
目前仅实现动画,内容没有填充,效果如下图
布局分析
承载日历网格的是一个ViewPager,每天的日历活动是一个ListView,需要实现的效果是,在listview区域向上滑动,viewpager也跟着滑动,滑动后viewpaer只留下一行,listview滑动到这一行的下面。
难点在于拦截listview的滑动事件。
实现分析
使用CalendarContainer(继承自FrameLayout)作为ViewPager和listView的父空间,在CalendarContainer的onInterceptTouchEvent中判断拦截listview的滑动事件,并处理滑动动画。
CalendarContainer类文件;
package com.example.test;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;
/**
* @author whuthm
* @date 2015-6-12
*/
public class CalendarContainer extends FrameLayout {
/** 停止滚动 */
public static final int SCROLL_STATE_IDLE = 0;
/** 手指在屏幕上正在滚动 */
public static final int SCROLL_STATE_TOUCH_SCROLL = 1;
/** 手指离开屏幕滚动 */
public static final int SCROLL_STATE_FLING = 2;
private int mScrollState = SCROLL_STATE_IDLE;
private VelocityTracker mVelocityTracker;
private CalendarListView mListView;
private CalendarViewPager mViewPager;
private int mRowHeight = 150;
private int mRowCount = 5;
private int mSelecteRow = 2;
private float mLastMotionY;
private boolean mIsOnSlidablyArea = false;
private int mTouchSlop;
/** view是否展开 */
private boolean mExpanded = true;
public CalendarContainer(Context context) {
this(context, null);
}
public CalendarContainer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CalendarContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final ViewConfiguration configuration = ViewConfiguration
.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mViewPager = new C