Android进阶篇广告控件

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();
    }
}
原文地址:https://www.cnblogs.com/gongcb/p/2715613.html