自定义view————广告弹窗

今天给大家带来自定义view————广告弹窗,效果图中的照片文字都是随便找的,实际项目中根据UI的设计稍微修改修改基本上就能达到预想的效果了(注:女神刘亦菲的图是好好找的!!!)

效果图

效果图看完了,接下来分析一下实现过程,首先整体是继承Dialog去实现的,组合自定义view达到预想效果,倒计时是一个画圈圈的过程,接下来详细讲解吧

画给倒计时的圈圈

一个背景色的底盘drawCircle(),一个画圈圈drawArc(),一个文字的显示,今天这里的文字显示采取了一个新的实现方式StaticLayout(android中处理文字换行的一个工具类)

//画底盘
        canvas.drawCircle(width / 2, height / 2, min / 2, circlePaint);
        //画边框
        RectF rectF;
        if (width > height) {
            rectF = new RectF(width / 2 - min / 2 + borderWidth / 2, 0 + borderWidth / 2, width / 2 + min / 2 - borderWidth / 2, height - borderWidth / 2);
        } else {
            rectF = new RectF(borderWidth / 2, height / 2 - min / 2 + borderWidth / 2, width - borderWidth / 2, height / 2 - borderWidth / 2 + min / 2);
        }
        canvas.drawArc(rectF, -90, progress, false, borderPaint);
        //画居中的文字
        canvas.translate(width / 2, height / 2 - staticLayout.getHeight() / 2);
        staticLayout.draw(canvas);复制代码

看到这里staticLayout是那里来的呀,看下面就知道了

    int textWidth = (int) textPaint.measureText(text.substring(0, text.length()));
        staticLayout = new StaticLayout(text, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 1F, 0, false);复制代码

静态的圈圈背景都已经就位,现在开始执行倒计时动画,这里写的是5s

是时候让圈圈动起来了

这里采用倒计时器来倒计时然后通知刷新动画


   //倒计时
     public void start() {
         if (listener != null) {
             listener.onStartCount();
         }
         //倒计时器     第一个参数表示总时间,第二个参数表示间隔时间
         new CountDownTimer((long) lastTime, 30) {
             @Override
             public void onTick(long millisUntilFinished) {
                 progress = 360 - ((lastTime - millisUntilFinished) / lastTime) * 360;
                 invalidate();
             }

             @Override
             public void onFinish() {
                 progress = 0;
                 invalidate();
                 if (listener != null) {
                     listener.onFinishCount();
                 }
             }
         }.start();
     }复制代码

倒计时的准备工作做好了,将倒计时的完整代码奉上

/**
 * Created by Administrator on 2017/8/10.
 * 广告倒计时
 *
 * @auther madreain
 */

public class CountDownView extends View {

    private static final int BACKGROUND_COLOR = 0x50555555;
    private static final float BORDER_WIDTH = 15f;
    private static final int BORDER_COLOR = 0xFF6ADBFE;
    private static final String TEXT = "跳过";
    private static final float TEXT_SIZE = 50f;
    private static final int TEXT_COLOR = 0xFFFFFFFF;

    int width;
    int height;
    int min;

    private int backgroundColor;
    private float borderWidth;
    private int borderColor;
    private String text;
    private int textColor;
    private float textSize;

    private Paint circlePaint;
    private TextPaint textPaint;
    private Paint borderPaint;

    private float progress = 360;
    private StaticLayout staticLayout;

    private CountDownTimerListener listener;

    //倒计时 显示5秒什么的
    float lastTime = 5000;

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

    public CountDownView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CountDownView);
        backgroundColor = ta.getColor(R.styleable.CountDownView_background_color, BACKGROUND_COLOR);
        borderWidth = ta.getDimension(R.styleable.CountDownView_borders_width, BORDER_WIDTH);
        borderColor = ta.getColor(R.styleable.CountDownView_borders_color, BORDER_COLOR);
        text = ta.getString(R.styleable.CountDownView_text);
        if (text == null) {
            text = TEXT;
        }
        textSize = ta.getDimension(R.styleable.CountDownView_text_size, TEXT_SIZE);
        textColor = ta.getColor(R.styleable.CountDownView_text_color, TEXT_COLOR);
        ta.recycle();
        init();
    }

    private void init() {
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setDither(true);
        circlePaint.setColor(backgroundColor);
        circlePaint.setStyle(Paint.Style.FILL);

        textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setDither(true);
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);
        textPaint.setTextAlign(Paint.Align.CENTER);

        borderPaint = new Paint();
        borderPaint.setAntiAlias(true);
        borderPaint.setDither(true);
        borderPaint.setColor(borderColor);
        borderPaint.setStrokeWidth(borderWidth);
        borderPaint.setStyle(Paint.Style.STROKE);

        int textWidth = (int) textPaint.measureText(text.substring(0, text.length()));
        staticLayout = new StaticLayout(text, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 1F, 0, false);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (widthMode != MeasureSpec.EXACTLY) {
            width = staticLayout.getWidth();
        }
        if (heightMode != MeasureSpec.EXACTLY) {
            height = staticLayout.getHeight();
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width=w;
        height=h;
        min = Math.min(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //画底盘
        canvas.drawCircle(width / 2, height / 2, min / 2, circlePaint);
        //画边框
        RectF rectF;
        if (width > height) {
            rectF = new RectF(width / 2 - min / 2 + borderWidth / 2, 0 + borderWidth / 2, width / 2 + min / 2 - borderWidth / 2, height - borderWidth / 2);
        } else {
            rectF = new RectF(borderWidth / 2, height / 2 - min / 2 + borderWidth / 2, width - borderWidth / 2, height / 2 - borderWidth / 2 + min / 2);
        }
        canvas.drawArc(rectF, -90, progress, false, borderPaint);
        //画居中的文字
        canvas.translate(width / 2, height / 2 - staticLayout.getHeight() / 2);
        staticLayout.draw(canvas);
    }


    //倒计时
    public void start() {
        if (listener != null) {
            listener.onStartCount();
        }
        //倒计时器     第一个参数表示总时间,第二个参数表示间隔时间
        new CountDownTimer((long) lastTime, 30) {
            @Override
            public void onTick(long millisUntilFinished) {
                progress = 360 - ((lastTime - millisUntilFinished) / lastTime) * 360;
                invalidate();
            }

            @Override
            public void onFinish() {
                progress = 0;
                invalidate();
                if (listener != null) {
                    listener.onFinishCount();
                }
            }
        }.start();
    }

    public void setCountDownTimerListener(CountDownTimerListener listener) {
        this.listener = listener;
    }

    public interface CountDownTimerListener {
        void onStartCount();

        void onChangeCount(int second);

        void onFinishCount();
    }
}复制代码

广告弹窗

广告弹窗上的倒计时已经准备好了,开始组合自定义view的撰写了,后期实际项目开发中,这一块可以根据实际情况修改组合的view布局

/**
 * Created by Administrator on 2017/8/10.
 * 闪屏广告
 *
 * @auther madreain
 */

public class SplashDialog extends Dialog {

    private Context mContext;
    //展示的
    AdvertisingImgModel advertisingImgModel;

    //背景照片
    private ImageView img_background;
    //倒计时
    private CountDownView count_down_view;

    private OnSplashDetailClickListener onSplashDetailClickListener;

    public SplashDialog(Context context, AdvertisingImgModel advertisingImgModel) {
        super(context, R.style.ADDialog);
        mContext = context;
        this.advertisingImgModel = advertisingImgModel;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_dialog);
        full(true);
        initView();
    }

    /**
     * @param enable false 显示,true 隐藏
     */
    private void full(boolean enable) {
        WindowManager.LayoutParams p = this.getWindow().getAttributes();
        if (enable) {

            p.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;//|=:或等于,取其一

        } else {
            p.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);//&=:与等于,取其二同时满足,     ~ : 取反

        }
        getWindow().setAttributes(p);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

    private void initView() {

        img_background = (ImageView) findViewById(R.id.img_background);
        Glide.with(mContext).load(advertisingImgModel.getImgurl()).into(img_background);
        //广告倒计时
        count_down_view = (CountDownView) findViewById(R.id.count_down_view);
        count_down_view.setCountDownTimerListener(new CountDownView.CountDownTimerListener() {
            @Override
            public void onStartCount() {

            }

            @Override
            public void onChangeCount(int second) {

            }

            @Override
            public void onFinishCount() {
                dismiss();
            }
        });
        //启动倒计时
        count_down_view.start();
        //点击跳过按钮
        count_down_view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        //点击事件
        img_background.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onSplashDetailClickListener != null) {
                    onSplashDetailClickListener.onSplashDetailClick(advertisingImgModel);
                }
                dismiss();
            }
        });

    }


    public void setOnSplashDetailClickListener(OnSplashDetailClickListener onSplashDetailClickListener) {
        this.onSplashDetailClickListener = onSplashDetailClickListener;
    }

    public interface OnSplashDetailClickListener {
        void onSplashDetailClick(AdvertisingImgModel advertisingImgModel);
    }

}复制代码

代码中使用

  txt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AdvertisingImgModel advertisingImgModel = new AdvertisingImgModel(1, "http://bmob-cdn-10899.b0.upaiyun.com/2017/05/09/34b6d85c406894f3803d949a78c4546e.jpg");
                splashDialog = new SplashDialog(MainActivity.this, advertisingImgModel);
                splashDialog.setOnSplashDetailClickListener(new SplashDialog.OnSplashDetailClickListener() {
                    @Override
                    public void onSplashDetailClick(AdvertisingImgModel advertisingImgModel) {
                        Toast.makeText(MainActivity.this, "跳转到广告的详情页", Toast.LENGTH_SHORT).show();
                    }
                });
                splashDialog.show();
            }
        });复制代码

大家如果有什么好的自定义view推荐练手的,欢迎留言

SplashView github demo

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值