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(); } }