博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义view————广告弹窗
阅读量:6587 次
发布时间:2019-06-24

本文共 10816 字,大约阅读时间需要 36 分钟。

今天给大家带来自定义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推荐练手的,欢迎留言

转载地址:http://qrhno.baihongyu.com/

你可能感兴趣的文章
《C语言及程序设计》实践参考——太乐了
查看>>
Web项目中使用Spring 3.x + Quartz 2.x实现作业调度详解
查看>>
[LeetCode]--60. Permutation Sequence
查看>>
YARN REST API
查看>>
swing Ctrl+S 保存配置
查看>>
Java学习之——泛型
查看>>
jQuery UI dialog实现dialog弹框显示
查看>>
[工具类]将时间转换为unix时间戳格式
查看>>
在阿里云上遇见更好的Oracle(四)
查看>>
重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)
查看>>
C# 判断远程文件是否存在
查看>>
backbone学习笔记:集合(Collection)
查看>>
[C#基础]说说委托+=和-=的那些事
查看>>
SSH原理与运用(一):远程登录
查看>>
Spring Framework 4.2 中的新功能和增强功能
查看>>
动态代理解决网站字符集编码
查看>>
C#中Encoding.Unicode与Encoding.UTF8的区别
查看>>
Spring中的AOP(二)——AOP基本概念和Spring对AOP的支持
查看>>
MarkDown的使用
查看>>
图像处理------简单脸谱检测算法
查看>>