动态轮播图,banner切换动画效果

 

    轮播图  可以实现动图gif  滑动切换动态效果展示, 一个自定义的飘落雪花的功能,(让我用来实现下红包雨的功能了)

    废话不多说  直接 上图   

 

 

上面轮播图  可以切换滑动效果, 有很多种滑动,自己去试吧(可能在处理滑动的时候没有考虑动图优化, 有点小卡顿, 如果有兴趣就自己看看源码)

 

下面是切换滑动特效

private void switchAnimation() {
        try {
            if (!mPresenter.getTransformerData().isEmpty()) {
                if (mPresenter.getTransformerData().size() == index) {
                    index = 0;
                }
                mTransforemerName = mPresenter.getTransformerData().get(index);
                Class cls = Class.forName("com.ToxicBakery.viewpager.transforms." + mTransforemerName);
                mTransforemer = (ABaseTransformer) cls.newInstance();
                mBanner.setPageTransformer(mTransforemer);
                mBanner.getViewPager().setPageTransformer(true, mTransforemer);
                //部分3D特效需要调整滑动速度
                if (mTransforemerName.equals("StackTransformer")) {
                    mBanner.setScrollDuration(1200);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    然后是设置banner数据

@Override
    public void refreshData(List<String> data) {
        if (!mPresenter.isDataMissing()) return;
        switchAnimation();
        mBanner.setPages(new CBViewHolderCreator<ViewHolder>() {
            @Override
            public ViewHolder createHolder() {
                return new ViewHolder();
            }
        }, data).setPageIndicator(new int[]{R.drawable.ic_page_indicator, R.drawable.ic_page_indicator_focused})
                .setPageIndicatorAlign(ConvenientBanner.PageIndicatorAlign.ALIGN_PARENT_RIGHT)
                .setPageTransformer(mTransforemer)
                .startTurning(3000);
    }

还有个实现类ViewHolder  需要实现Holder

public class ViewHolder implements Holder<String> {

    private GifImageView imageView;

    @Override
    public View createView(Context context) {
        imageView = new GifImageView(context);
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        return imageView;
    }

    @Override
    public void UpdateUI(Context context, int position, String data) {
        if (data.length() > 3) {
            if (data.substring(data.length() - 3).equals("gif")) {
                try {
                    byte[] bytes = new GifDataAsyncTask().execute(data).get();
                    imageView.setBytes(bytes);
                    imageView.startAnimation();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                Picasso.with(context).load(data).into(imageView);
            }
        }
    }
}

以上基本就是轮播图了, 还算是比较简单

下面说一下 下红包雨的功能

两种实现方式, 都是自定义类

一种继承  SurfaceView 实现  SurfaceHolder.Callback 方法

public class Snow extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private SnowFlake[]   mFlakes;
    private int           mViewWidth  = 200;
    private int           mViewHeight = 100;
    private int           mFlakeCount = 20;
    private int           mMinSize    = 50;
    private int           mMaxSize    = 70;
    private int           mSpeedX     = 10;
    private int           mSpeedY     = 20;
    private Bitmap mSnowBitmap = null;
    private boolean       mStart      = false;

    public Snow(Context context) {
        this(context, null);
    }

    public Snow(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Snow(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHolder();
        setZOrderOnTop(true);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Snow, defStyleAttr, 0);
        int cnt = array.getIndexCount();
        for (int i = 0; i < cnt; i++) {
            int attr = array.getIndex(i);
            switch (attr) {
            case R.styleable.Snow_flakeCount:
                mFlakeCount = array.getInteger(attr, 0);
                break;
            case R.styleable.Snow_minSize:
                mMinSize = array.getInteger(attr, 50);
                break;
            case R.styleable.Snow_maxSize:
                mMaxSize = array.getInteger(attr, 70);
                break;
            case R.styleable.Snow_flakeSrc:
                Integer srcId = array.getResourceId(attr, R.drawable.snow_flake);
                mSnowBitmap   = BitmapFactory.decodeResource(getResources(), srcId);
                break;
            case R.styleable.Snow_speedX:
                mSpeedX = array.getInteger(attr, 10);
                break;
            case R.styleable.Snow_speedY:
                mSpeedY = array.getInteger(attr, 10);
                break;
            default:
                break;
            }
        }
        if (mMinSize > mMaxSize) {
            mMaxSize = mMinSize;
        }
        array.recycle();
    }

    private void initHolder() {
        mHolder = this.getHolder();
        mHolder.setFormat(PixelFormat.TRANSLUCENT);
        mHolder.addCallback(this);
    }

    private void initSnowFlakes() {
        mFlakes = new SnowFlake[mFlakeCount];
        boolean isRightDir = new Random().nextBoolean();
        for (int i = 0; i < mFlakes.length; i++) {
            mFlakes[i] = new SnowFlake();
            mFlakes[i].setWidth(new Random().nextInt(mMaxSize-mMinSize) + mMinSize);
            mFlakes[i].setHeight(mFlakes[i].getWidth());
            mFlakes[i].setX(new Random().nextInt(mViewWidth));
            mFlakes[i].setY(-(new Random().nextInt(mViewHeight)));
            mFlakes[i].setSpeedY(new Random().nextInt(4) + mSpeedY);
            if (isRightDir) {
                mFlakes[i].setSpeedX(new Random().nextInt(4) + mSpeedX);
            }
            else {
                mFlakes[i].setSpeedX(-(new Random().nextInt(4) + mSpeedX));
            }
        }
    }

    private void updatePara() {
        int x;
        int y;
        for (SnowFlake flake : mFlakes) {
            if (flake == null) {
                break;
            }
            x = flake.getX() + flake.getSpeedX();
            y = flake.getY() + flake.getSpeedY();
            if ((x > mViewWidth + 20 || x < 0)
                    || (y > mViewHeight + 20)) {
                x = new Random().nextInt(mViewWidth);
                y = 0;
            }
            flake.setX(x);
            flake.setY(y);
        }
    }

    private void drawView() {
        if (mHolder == null) {
            return;
        }
        Canvas canvas = mHolder.lockCanvas();
        if (canvas == null) {
            return;
        }
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        drawSnow(canvas);
        mHolder.unlockCanvasAndPost(canvas);
    }

    private void drawSnow(Canvas canvas) {
        Rect rect  = new Rect();
        Paint paint = new Paint();
        for (SnowFlake flake : mFlakes) {
            rect.left   = flake.getX();
            rect.top    = flake.getY();
            rect.right  = rect.left + flake.getWidth();
            rect.bottom = rect.top  + flake.getHeight();
            canvas.drawBitmap(mSnowBitmap, null, rect, paint);
        }
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        mStart = (visibility == VISIBLE);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initSnowFlakes();
        start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //--- measure the view's width
        int widthMode  = MeasureSpec.getMode(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
        } else {
            mViewWidth = (getPaddingStart() + mSnowBitmap.getWidth() + getPaddingEnd());
        }

        //--- measure the view's height
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
        } else {
            mViewHeight = (getPaddingTop() + mSnowBitmap.getHeight() + getPaddingBottom());
        }

        setMeasuredDimension(mViewWidth, mViewHeight);
    }

    public void start() {
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    try {
                        if (mStart) {
                            updatePara();
                            drawView();
                        }
                        Thread.sleep(20);
                    }
                    catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }.start();
    }
}

另一种直接继承View 

public class FallingView extends View {

    private boolean mStart = false;
    private List<FallObject> fallObjects;

    private int viewWidth;
    private int viewHeight;

    private static final int defaultWidth = 600;//默认宽度
    private static final int defaultHeight = 1000;//默认高度
    private static final int intervalTime = 5;//重绘间隔时间

    public FallingView(Context context) {
        super(context);
        init();
    }

    public FallingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        fallObjects = new ArrayList<>();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = measureSize(defaultHeight, heightMeasureSpec);
        int width = measureSize(defaultWidth, widthMeasureSpec);
        setMeasuredDimension(width, height);

        viewWidth = width;
        viewHeight = height;
    }

    private int measureSize(int defaultSize, int measureSpec) {
        int result = defaultSize;
        int specMode = View.MeasureSpec.getMode(measureSpec);
        int specSize = View.MeasureSpec.getSize(measureSpec);

        if (specMode == View.MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == View.MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        mStart = (visibility == VISIBLE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 只有在显示的时候才会去绘制
        if (mStart){
            if (fallObjects.size() > 0) {
                for (int i = 0; i < fallObjects.size(); i++) {
                    //然后进行绘制
                    fallObjects.get(i).drawObject(canvas);
                }
                // 隔一段时间重绘一次, 动画效果
                getHandler().postDelayed(runnable, intervalTime);
            }
        }
    }

    // 重绘线程
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            invalidate();
        }
    };

    /**
     * 向View添加下落物体对象
     *
     * @param fallObject 下落物体对象
     * @param num
     */
    public void addFallObject(final FallObject fallObject, final int num) {
        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                getViewTreeObserver().removeOnPreDrawListener(this);
                for (int i = 0; i < num; i++) {
                    FallObject newFallObject = new FallObject(fallObject.builder, viewWidth, viewHeight);
                    fallObjects.add(newFallObject);
                }
                invalidate();
                return true;
            }
        });
    }
}

但这种需要一个容器  来设置一些参数

在调用的时候

 private void start(){
        //初始化一个雪花样式的fallObject
        FallObject.Builder builder = new FallObject.Builder(getResources(), R.drawable.hongbao);
        FallObject fallObject = builder
                .setSpeed(7,true) // 设置物体的初始下落速度
                .setSize(50,50,true) // 设置物体大小
                .setWind(5,true,true) // 设置风力等级、方向以及随机因素
                .build();
        fallingView.addFallObject(fallObject,50);//添加50个下落物体对象
    }

两种哪种都可以实现, 具体还是看需求

下载地址:https://github.com/xiaobinAndroid421726260/Android_SnowBanner2019_11_5Demo.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值