今天給大家帶來自定義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推薦練手的,歡迎留言