Android 天气APP(十三)仿微信弹窗(右上角加号点击弹窗效果)、自定义背景图片、UI优化调整

paint.setStyle(Paint.Style.STROKE);

paint.setColor(color);

paint.setStrokeWidth(lineWidth);

canvas.drawLine(

sx, sy, ex, ey,

paint);

}

/**

  • 绘制关闭状态指示器

  • @param canvas

*/

private void drawUncheckIndicator(Canvas canvas) {

drawUncheckIndicator(canvas,

uncheckCircleColor,

uncheckCircleWidth,

right - uncheckCircleOffsetX, centerY,

uncheckCircleRadius,

paint);

}

/**

  • 绘制关闭状态指示器

  • @param canvas

  • @param color

  • @param lineWidth

  • @param centerX

  • @param centerY

  • @param radius

  • @param paint

*/

protected void drawUncheckIndicator(Canvas canvas,

int color,

float lineWidth,

float centerX, float centerY,

float radius,

Paint paint) {

paint.setStyle(Paint.Style.STROKE);

paint.setColor(color);

paint.setStrokeWidth(lineWidth);

canvas.drawCircle(centerX, centerY, radius, paint);

}

/**

  • @param canvas

  • @param left

  • @param top

  • @param right

  • @param bottom

  • @param startAngle

  • @param sweepAngle

  • @param paint

*/

private void drawArc(Canvas canvas,

float left, float top,

float right, float bottom,

float startAngle, float sweepAngle,

Paint paint){

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

canvas.drawArc(left, top, right, bottom,

startAngle, sweepAngle, true, paint);

}else{

rect.set(left, top, right, bottom);

canvas.drawArc(rect,

startAngle, sweepAngle, true, paint);

}

}

/**

  • @param canvas

  • @param left

  • @param top

  • @param right

  • @param bottom

  • @param backgroundRadius

  • @param paint

*/

private void drawRoundRect(Canvas canvas,

float left, float top,

float right, float bottom,

float backgroundRadius,

Paint paint){

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

canvas.drawRoundRect(left, top, right, bottom,

backgroundRadius, backgroundRadius, paint);

}else{

rect.set(left, top, right, bottom);

canvas.drawRoundRect(rect,

backgroundRadius, backgroundRadius, paint);

}

}

/**

  • @param canvas

  • @param x px

  • @param y px

*/

private void drawButton(Canvas canvas, float x, float y) {

canvas.drawCircle(x, y, buttonRadius, buttonPaint);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(1);

paint.setColor(0XffDDDDDD);

canvas.drawCircle(x, y, buttonRadius, paint);

}

@Override

public void setChecked(boolean checked) {

if(checked == isChecked()){

postInvalidate();

return;

}

toggle(enableEffect, false);

}

@Override

public boolean isChecked() {

return isChecked;

}

@Override

public void toggle() {

toggle(true);

}

/**

  • 切换状态

  • @param animate

*/

public void toggle(boolean animate) {

toggle(animate, true);

}

private void toggle(boolean animate, boolean broadcast) {

if(!isEnabled()){return;}

if(isEventBroadcast){

throw new RuntimeException(“should NOT switch the state in method: [onCheckedChanged]!”);

}

if(!isUiInited){

isChecked = !isChecked;

if(broadcast){

broadcastEvent();

}

return;

}

if(valueAnimator.isRunning()){

valueAnimator.cancel();

}

if(!enableEffect || !animate){

isChecked = !isChecked;

if(isChecked()){

setCheckedViewState(viewState);

}else{

setUncheckViewState(viewState);

}

postInvalidate();

if(broadcast){

broadcastEvent();

}

return;

}

animateState = ANIMATE_STATE_SWITCH;

beforeState.copy(viewState);

if(isChecked()){

//切换到unchecked

setUncheckViewState(afterState);

}else{

setCheckedViewState(afterState);

}

valueAnimator.start();

}

/**

*/

private void broadcastEvent() {

if(onCheckedChangeListener != null){

isEventBroadcast = true;

onCheckedChangeListener.onCheckedChanged(this, isChecked());

}

isEventBroadcast = false;

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if(!isEnabled()){return false;}

int actionMasked = event.getActionMasked();

switch (actionMasked){

case MotionEvent.ACTION_DOWN:{

isTouchingDown = true;

touchDownTime = System.currentTimeMillis();

//取消准备进入拖动状态

removeCallbacks(postPendingDrag);

//预设100ms进入拖动状态

postDelayed(postPendingDrag, 100);

break;

}

case MotionEvent.ACTION_MOVE:{

float eventX = event.getX();

if(isPendingDragState()){

//在准备进入拖动状态过程中,可以拖动按钮位置

float fraction = eventX / getWidth();

fraction = Math.max(0f, Math.min(1f, fraction));

viewState.buttonX = buttonMinX

  • (buttonMaxX - buttonMinX)
  • fraction;

}else if(isDragState()){

//拖动按钮位置,同时改变对应的背景颜色

float fraction = eventX / getWidth();

fraction = Math.max(0f, Math.min(1f, fraction));

viewState.buttonX = buttonMinX

  • (buttonMaxX - buttonMinX)
  • fraction;

viewState.checkStateColor = (int) argbEvaluator.evaluate(

fraction,

uncheckColor,

checkedColor

);

postInvalidate();

}

break;

}

case MotionEvent.ACTION_UP:{

isTouchingDown = false;

//取消准备进入拖动状态

removeCallbacks(postPendingDrag);

if(System.currentTimeMillis() - touchDownTime <= 300){

//点击时间小于300ms,认为是点击操作

toggle();

}else if(isDragState()){

//在拖动状态,计算按钮位置,设置是否切换状态

float eventX = event.getX();

float fraction = eventX / getWidth();

fraction = Math.max(0f, Math.min(1f, fraction));

boolean newCheck = fraction > .5f;

if(newCheck == isChecked()){

pendingCancelDragState();

}else{

isChecked = newCheck;

pendingSettleState();

}

}else if(isPendingDragState()){

//在准备进入拖动状态过程中,取消之,复位

pendingCancelDragState();

}

break;

}

case MotionEvent.ACTION_CANCEL:{

isTouchingDown = false;

removeCallbacks(postPendingDrag);

if(isPendingDragState()

|| isDragState()){

//复位

pendingCancelDragState();

}

break;

}

}

return true;

}

/**

  • 是否在动画状态

  • @return

*/

private boolean isInAnimating(){

return animateState != ANIMATE_STATE_NONE;

}

/**

  • 是否在进入拖动或离开拖动状态

  • @return

*/

private boolean isPendingDragState(){

return animateState == ANIMATE_STATE_PENDING_DRAG

|| animateState == ANIMATE_STATE_PENDING_RESET;

}

/**

  • 是否在手指拖动状态

  • @return

*/

private boolean isDragState(){

return animateState == ANIMATE_STATE_DRAGING;

}

/**

  • 设置是否启用阴影效果

  • @param shadowEffect true.启用

*/

public void setShadowEffect(boolean shadowEffect) {

if(this.shadowEffect == shadowEffect){return;}

this.shadowEffect = shadowEffect;

if(this.shadowEffect){

buttonPaint.setShadowLayer(

shadowRadius,

0, shadowOffset,

shadowColor);

}else{

buttonPaint.setShadowLayer(

0,

0, 0,

0);

}

}

public void setEnableEffect(boolean enable){

this.enableEffect = enable;

}

/**

  • 开始进入拖动状态

*/

private void pendingDragState() {

if(isInAnimating()){return;}

if(!isTouchingDown){return;}

if(valueAnimator.isRunning()){

valueAnimator.cancel();

}

animateState = ANIMATE_STATE_PENDING_DRAG;

beforeState.copy(viewState);

afterState.copy(viewState);

if(isChecked()){

afterState.checkStateColor = checkedColor;

afterState.buttonX = buttonMaxX;

afterState.checkedLineColor = checkedColor;

}else{

afterState.checkStateColor = uncheckColor;

afterState.buttonX = buttonMinX;

afterState.radius = viewRadius;

}

valueAnimator.start();

}

/**

  • 取消拖动状态

*/

private void pendingCancelDragState() {

if(isDragState() || isPendingDragState()){

if(valueAnimator.isRunning()){

valueAnimator.cancel();

}

animateState = ANIMATE_STATE_PENDING_RESET;

beforeState.copy(viewState);

if(isChecked()){

setCheckedViewState(afterState);

}else{

setUncheckViewState(afterState);

}

valueAnimator.start();

}

}

/**

  • 动画-设置新的状态

*/

private void pendingSettleState() {

if(valueAnimator.isRunning()){

valueAnimator.cancel();

}

animateState = ANIMATE_STATE_PENDING_SETTLE;

beforeState.copy(viewState);

if(isChecked()){

setCheckedViewState(afterState);

}else{

setUncheckViewState(afterState);

}

valueAnimator.start();

}

@Override

public final void setOnClickListener(OnClickListener l) {}

@Override

public final void setOnLongClickListener(OnLongClickListener l) {}

public void setOnCheckedChangeListener(OnCheckedChangeListener l){

onCheckedChangeListener = l;

}

public interface OnCheckedChangeListener{

void onCheckedChanged(SwitchButton view, boolean isChecked);

}

/*******************************************************/

private static float dp2px(float dp){

Resources r = Resources.getSystem();

return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());

}

private static int dp2pxInt(float dp){

return (int) dp2px(dp);

}

private static int optInt(TypedArray typedArray,

int index,

int def) {

if(typedArray == null){return def;}

return typedArray.getInt(index, def);

}

private static float optPixelSize(TypedArray typedArray,

int index,

float def) {

if(typedArray == null){return def;}

return typedArray.getDimension(index, def);

}

private static int optPixelSize(TypedArray typedArray,

int index,

int def) {

if(typedArray == null){return def;}

return typedArray.getDimensionPixelOffset(index, def);

}

private static int optColor(TypedArray typedArray,

int index,

int def) {

if(typedArray == null){return def;}

return typedArray.getColor(index, def);

}

private static boolean optBoolean(TypedAr

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值