package com.cn.teachmobile.view;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.ViewFlipper;
/**
* @author gongchaobin
*
* 广告控件
*/
public abstract class FlingGallery extends RelativeLayout{
//重新开启自动播放
private Handler fHandler;
private Runnable fRunnable;
//底图
private FrameLayout bottomFrameLayout;
//视图播放view
private ViewFlipper viewFlipper;
private int mViewFlipInterval = 3000;
//baseAdapter
private BaseAdapter baseAdapter;
//视图与视图之间的偏移量
private float viewOffset = 0.005f;
//动画是否左移
private boolean leftMove = true;
//动画时间
private long durationMillis = 200l;
//当前pageNumber
private int currentPageNumber;
//======================================= onTouchEvent =========================================
//左右滑动切换
private float rawX;
//当前移动的距离
private float currentMoveDistance;
//当前视图
private View currentView;
//下一个视图
private View nextView;
//最小滑动距离
private float minMoveDistance = 50f;
/**
* @param context
*/
public FlingGallery(Context context) {
super(context);
layout(context);
}
/**
* @param context
* @param attrs
*/
public FlingGallery(Context context, AttributeSet attrs) {
super(context, attrs);
layout(context);
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public FlingGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout(context);
}
/**
* 初始化布局方法
* @param context
*/
private void layout(Context context){
/** 添加底图 */
bottomFrameLayout = new FrameLayout(context);
/** 加载到父控件中 */
final RelativeLayout.LayoutParams bottomFrameLayoutParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
bottomFrameLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_TOP);
bottomFrameLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
this.addView(bottomFrameLayout, bottomFrameLayoutParam);
viewFlipper = new ViewFlipper(context){
/**
* 修复ViewFlipper的一个bug
*/
public void onDetachedFromWindow() {
try {
super.onDetachedFromWindow();
} catch (Exception e) {
this.stopFlipping();
}
}
public void setDisplayedChild(int whichChild) {
super.setDisplayedChild(whichChild);
currentPageNumber = whichChild >= baseAdapter.getCount() ? 0 : (whichChild < 0 ? baseAdapter.getCount() - 1 : whichChild);
setCurrentPageNumber(currentPageNumber);
}
};
/** 设置进入进出动画 */
viewFlipper.setInAnimation(getInMoveAnimation(0f));
viewFlipper.setOutAnimation(getOutMoveAnimation(0f));
/** 加载到父控件中 */
final RelativeLayout.LayoutParams viewFlipperParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
viewFlipperParam.addRule(RelativeLayout.ALIGN_PARENT_TOP);
viewFlipperParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
this.addView(viewFlipper, viewFlipperParam);
}
/**
* 获取进入动画
* @param scrollXRelativePersent 有正负之分
* @return
*/
private Animation getInMoveAnimation(float scrollXRelativePersent){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateInterpolator());
TranslateAnimation translateAnimation = null;
if(scrollXRelativePersent == 0f){
translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, leftMove ? 1f + viewOffset : -1f - viewOffset,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
} else{
translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, - scrollXRelativePersent,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
translateAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
if(bottomFrameLayout.getChildCount() > 0){
bottomFrameLayout.removeAllViews();
}
}
});
}
translateAnimation.setDuration(durationMillis);
animationSet.addAnimation(translateAnimation);
return animationSet;
}
/**
* 获取离开动画
* @param scrollXRelativePersent 有正负之分
* @return
*/
private Animation getOutMoveAnimation(float scrollXRelativePersent){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateInterpolator());
TranslateAnimation translateAnimation = null;
if(scrollXRelativePersent == 0f){
translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, leftMove ? -1f : 1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
} else{
translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, - scrollXRelativePersent,
Animation.RELATIVE_TO_SELF, scrollXRelativePersent > 0f ? -1f : 1f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
translateAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
if(currentView != null){
currentView.scrollTo(0, 0);
}
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
}
});
}
translateAnimation.setDuration(durationMillis);
animationSet.addAnimation(translateAnimation);
return animationSet;
}
/**
* 获取还原动画
* @param scrollXRelativePersent 有正负之分
* @return
*/
private Animation getBackInAnimation(float scrollXRelativePersent){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new DecelerateInterpolator());
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, - scrollXRelativePersent,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
translateAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
if(currentView != null){
currentView.scrollTo(0, 0);
}
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
}
});
translateAnimation.setDuration(durationMillis);
animationSet.addAnimation(translateAnimation);
return animationSet;
}
/**
* 获取还原动画
* @param scrollXRelativePersent 有正负之分
* @return
*/
private Animation getBackOutAnimation(float scrollXRelativePersent){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new DecelerateInterpolator());
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, - scrollXRelativePersent,
Animation.RELATIVE_TO_SELF, scrollXRelativePersent > 0f ? -1f : 1f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
translateAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
if(nextView != null){
nextView.scrollTo(0, 0);
}
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
if(bottomFrameLayout.getChildCount() > 0){
bottomFrameLayout.removeAllViews();
}
}
});
translateAnimation.setDuration(durationMillis);
animationSet.addAnimation(translateAnimation);
return animationSet;
}
/**
* 设置适配器
* @param baseAdapter
*/
public void setBaseAdapter(BaseAdapter baseAdapter) {
this.baseAdapter = baseAdapter;
if(viewFlipper.isFlipping()){
viewFlipper.stopFlipping();
}
if(viewFlipper.getChildCount() > 0){
viewFlipper.removeAllViews();
}
for (int i = 0; i < baseAdapter.getCount(); i++) {
final View baseChildView = baseAdapter.getView(i, null, null);
viewFlipper.addView(baseChildView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
}
/** 设置选中第一个 */
if(baseAdapter.getCount() > 0){
currentPageNumber = viewFlipper.getDisplayedChild() >= baseAdapter.getCount() ? 0 :
(viewFlipper.getDisplayedChild() < 0 ? baseAdapter.getCount() - 1 : viewFlipper.getDisplayedChild());
setCurrentPageNumber(currentPageNumber);
}
}
/**
* 获取适配器
* @return
*/
public BaseAdapter getBaseAdapter() {
return baseAdapter;
}
/**
* 获取当前pageNumber
* @return
*/
public int getCurrentPageNumber() {
return currentPageNumber;
}
/**
* 设置当前页码
* @param currentPageNumber
*/
protected abstract void setCurrentPageNumber(int currentPageNumber);
/**
* 设置动画时间间隔
* @param durationMillis
*/
public void setDurationMillis(long durationMillis) {
this.durationMillis = durationMillis;
}
/**
* 设置视图与视图之间的偏移量
* @param viewOffset
*/
public void setViewOffset(float viewOffset) {
this.viewOffset = viewOffset;
}
/**
* 设置动画是左移还是右移
* @param leftMove
*/
public void setLeftMove(boolean leftMove) {
this.leftMove = leftMove;
/** 设置进入进出动画 */
viewFlipper.setInAnimation(getInMoveAnimation(0f));
viewFlipper.setOutAnimation(getOutMoveAnimation(0f));
}
/**
* 设置 最小滑动距离
* @param minMoveDistance
*/
public void setMinMoveDistance(float minMoveDistance) {
this.minMoveDistance = minMoveDistance;
}
/**
* 设置按钮暂停,松开播放
*/
public boolean onTouchEvent(MotionEvent event) {
if(baseAdapter.getCount() > 1){
final int actionId = event.getAction();
if(actionId == MotionEvent.ACTION_DOWN){
/** 获取按下点坐标,并且停止播放 */
rawX = event.getRawX();
if(viewFlipper.isFlipping()){
viewFlipper.stopFlipping();
}
return true;
} else if(actionId == MotionEvent.ACTION_MOVE){
//获取当前移动距离
currentMoveDistance = rawX - event.getRawX();
if(currentMoveDistance <= (float) viewFlipper.getWidth()){
/** 重置当前视图和下一个视图 */
if(currentView != null){
currentView.scrollTo(0, 0);
}
if(bottomFrameLayout.getChildCount() > 0){
bottomFrameLayout.removeAllViews();
}
/** 移动 视图*/
if(Math.abs(currentMoveDistance) >= (minMoveDistance / 25f)){
/** 获取当前视图 */
currentView = viewFlipper.getChildAt(currentPageNumber);
/** 获取下一个视图 */
int nextPageNumber = currentPageNumber + (currentMoveDistance > 0f ? (leftMove ? 1 : -1) : (leftMove ? -1 : 1));
nextPageNumber = nextPageNumber < 0 ? (baseAdapter.getCount() - 1) : (nextPageNumber >= baseAdapter.getCount() ? 0 : nextPageNumber);
nextView = baseAdapter.getView(nextPageNumber, null, null);
bottomFrameLayout.addView(nextView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
currentView.scrollTo((int) currentMoveDistance, 0);
if(currentMoveDistance > 0f){
/** 左移 */
nextView.scrollTo((int) (currentMoveDistance - (float) bottomFrameLayout.getWidth()
- (viewOffset * (float) bottomFrameLayout.getWidth())), 0);
} else{
/** 右移 */
nextView.scrollTo((int) (currentMoveDistance + (float) bottomFrameLayout.getWidth()
+ (viewOffset * (float) bottomFrameLayout.getWidth())), 0);
}
}
}
return true;
} else if(actionId == MotionEvent.ACTION_UP){
//获取当前移动距离
currentMoveDistance = rawX - event.getRawX();
/** 切换动画 */
if(currentView != null && nextView != null && Math.abs(currentMoveDistance) >= minMoveDistance){
/** 设置进入进出动画 */
viewFlipper.setInAnimation(getInMoveAnimation((float) nextView.getScrollX() / (float) bottomFrameLayout.getWidth()));
viewFlipper.setOutAnimation(getOutMoveAnimation((float) currentView.getScrollX() / (float) viewFlipper.getWidth()));
if(currentMoveDistance > 0f){
if(leftMove){
viewFlipper.showNext();
} else{
viewFlipper.showPrevious();
}
} else{
if(leftMove){
viewFlipper.showPrevious();
} else{
viewFlipper.showNext();
}
}
} else if(currentView != null && nextView != null){
/** 重置当前视图和下一个视图 */
if(currentView != null){
currentView.startAnimation(getBackInAnimation((float) currentView.getScrollX() / (float) viewFlipper.getWidth()));
}
if(nextView != null){
nextView.startAnimation(getBackOutAnimation((float) nextView.getScrollX() / (float) bottomFrameLayout.getWidth()));
}
}
/** 若设置自动播放,则播放动画 */
if(viewFlipper.isAutoStart() && !viewFlipper.isFlipping()){
if(fHandler == null){
fHandler = new Handler();
}
if(fRunnable != null){
fHandler.removeCallbacks(fRunnable);
}
fRunnable = new Runnable() {
public void run() {
/** 重新加载动画 */
if(viewFlipper.getChildCount() > 0){
viewFlipper.removeAllViews();
}
for (int i = 0; i < baseAdapter.getCount(); i++) {
final View baseChildView = baseAdapter.getView(i, null, null);
viewFlipper.addView(baseChildView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
}
/** 播放动画 */
currentPageNumber += 1;
currentPageNumber = currentPageNumber >= baseAdapter.getCount() ? 0 : currentPageNumber;
viewFlipper.setInAnimation(getInMoveAnimation(0f));
viewFlipper.setOutAnimation(getOutMoveAnimation(0f));
viewFlipper.setDisplayedChild(currentPageNumber);
viewFlipper.startFlipping();
fRunnable = null;
}
};
fHandler.postDelayed(fRunnable, mViewFlipInterval + durationMillis);
}
return true;
}
}
return super.onTouchEvent(event);
}
//================================ viewFlipper =====================================
/**
* 设置自动开始
* @param autoStart
*/
public void setAutoStart(boolean autoStart){
viewFlipper.setAutoStart(autoStart);
}
/**
* 设置切换时间间隔
* @param milliseconds
*/
public void setFlipInterval(int milliseconds){
mViewFlipInterval = milliseconds;
viewFlipper.setFlipInterval(mViewFlipInterval);
}
/**
* 开始播放
*/
public void startFlipping(){
viewFlipper.startFlipping();
}
/**
* 停止播放
*/
public void stopFlipping(){
viewFlipper.stopFlipping();
}
/**
* 下一个视图
*/
public void showNext() {
viewFlipper.showNext();
}
/**
* 上一个视图
*/
public void showPrevious() {
viewFlipper.showPrevious();
}
/** 跳转到具体哪一个视图 */
public void moveToPosition(int position){
position = position < 0 ? 0 : (position >= baseAdapter.getCount() ? baseAdapter.getCount() - 1 : position);
viewFlipper.setDisplayedChild(position);
}
/**
* 是否为自动播放
* @return
*/
public boolean isAutoStart(){
return viewFlipper.isAutoStart();
}
/**
* 是否处于播放中
* @return
*/
public boolean isFlipping(){
return viewFlipper.isFlipping();
}
}