[sweeper-cloud]弹窗公共UI布局搭建
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
package com.mogo.och.sweepercloud.ui.dialog
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.text.Html
|
||||
import android.view.View
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
|
||||
import com.mogo.och.sweepercloud.R
|
||||
import com.mogo.och.sweepercloud.view.CountDownView
|
||||
|
||||
/**
|
||||
* 清扫车云控任务dialog基类
|
||||
*/
|
||||
class SweeperCloudDialog : BaseFloatDialog, LifecycleObserver {
|
||||
private var commonTitle: TextView? = null //标题
|
||||
private var commonLeft: TextView? = null//底部左边按钮
|
||||
private var commonMiddle: TextView? = null //底部中间按钮
|
||||
private var commonRight: TextView? = null //底部右边按钮
|
||||
private var commonCountDown: CountDownView? = null //倒计时
|
||||
private var commonContent: TextView? = null //内容
|
||||
private var commonTip: TextView? = null //文本提示
|
||||
private var countDownImage: ImageView? = null //内容
|
||||
private var objectAnimator: ObjectAnimator? = null
|
||||
|
||||
constructor(builder: Builder, context: Context) : super(context) {
|
||||
commonTitle?.text = builder.titleStr
|
||||
commonContent?.text = Html.fromHtml(builder.contentStr)
|
||||
if (builder.tipStr == "") {
|
||||
commonTip?.visibility = View.GONE
|
||||
} else {
|
||||
commonTip?.text = builder.tipStr
|
||||
}
|
||||
if (builder.leftStr == "") {
|
||||
commonLeft?.visibility = View.GONE
|
||||
} else {
|
||||
commonLeft?.text = builder.leftStr
|
||||
}
|
||||
if (builder.middleStr == "") {
|
||||
commonMiddle?.visibility = View.GONE
|
||||
} else {
|
||||
commonMiddle?.text = builder.middleStr
|
||||
}
|
||||
if (builder.rightStr == "") {
|
||||
commonRight?.visibility = View.GONE
|
||||
} else {
|
||||
commonRight?.text = builder.rightStr
|
||||
}
|
||||
if (builder.countDownTime == 0) {
|
||||
commonCountDown?.visibility = View.GONE
|
||||
} else {
|
||||
commonCountDown?.startCountDown(builder.countDownTime)
|
||||
}
|
||||
commonLeft?.setOnClickListener {
|
||||
builder.listener?.onConfirm()
|
||||
objectAnimator?.cancel()
|
||||
commonCountDown?.stopCountDown()
|
||||
dismiss()
|
||||
}
|
||||
commonMiddle?.setOnClickListener {
|
||||
builder.listener?.onNext()
|
||||
objectAnimator?.cancel()
|
||||
commonCountDown?.stopCountDown()
|
||||
dismiss()
|
||||
}
|
||||
commonRight?.setOnClickListener {
|
||||
builder.listener?.onRefuse()
|
||||
objectAnimator?.cancel()
|
||||
commonCountDown?.stopCountDown()
|
||||
dismiss()
|
||||
}
|
||||
commonCountDown?.setCountDownListener(object : CountDownView.CountDownListener {
|
||||
override fun stop() {
|
||||
builder.listener?.onCountDownStop()
|
||||
objectAnimator?.cancel()
|
||||
commonCountDown?.stopCountDown()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
})
|
||||
countDownImage?.let { startAnima(it) }
|
||||
}
|
||||
|
||||
init {
|
||||
setContentView(R.layout.dialog_sweeper_cloud_view)
|
||||
setCanceledOnTouchOutside(false)
|
||||
commonTitle = findViewById(R.id.sweeper_cloud_title)
|
||||
commonContent = findViewById(R.id.sweeper_cloud_content)
|
||||
commonTip = findViewById(R.id.sweeper_cloud_tip)
|
||||
commonLeft = findViewById(R.id.sweeper_cloud_left)
|
||||
commonMiddle = findViewById(R.id.sweeper_cloud_middle)
|
||||
commonRight = findViewById(R.id.sweeper_cloud_right)
|
||||
countDownImage = findViewById(R.id.sweeper_cloud_imageview)
|
||||
commonCountDown = findViewById(R.id.sweeper_cloud_countdown)
|
||||
}
|
||||
|
||||
interface SweeperCloudClickListener {
|
||||
fun onConfirm()
|
||||
fun onRefuse()
|
||||
fun onCountDownStop()
|
||||
fun onNext()
|
||||
}
|
||||
|
||||
class Builder {
|
||||
var titleStr: String = ""
|
||||
var contentStr: String = ""
|
||||
var tipStr: String = ""
|
||||
var leftStr: String = ""
|
||||
var middleStr: String = ""
|
||||
var rightStr: String = ""
|
||||
var countDownTime: Int = 0
|
||||
var listener: SweeperCloudClickListener? = null
|
||||
fun build(context: Context): SweeperCloudDialog {
|
||||
return SweeperCloudDialog(this, context)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动动画
|
||||
*/
|
||||
private fun startAnima(imageView: ImageView) {
|
||||
objectAnimator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 359f)
|
||||
objectAnimator?.repeatCount = ValueAnimator.INFINITE
|
||||
objectAnimator?.duration = 1500
|
||||
objectAnimator?.interpolator = LinearInterpolator()
|
||||
objectAnimator?.start()
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
package com.mogo.och.sweepercloud.view;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.och.sweepercloud.R;
|
||||
|
||||
/**
|
||||
* created by wujifei on 2021/3/24 16:20
|
||||
* describe:
|
||||
*/
|
||||
public class BusArcView extends View {
|
||||
|
||||
//中心的文字描述
|
||||
private String mDes = "KM/H";
|
||||
//根据数据显示的圆弧Paint
|
||||
private Paint mArcPaint;
|
||||
//圆弧颜色
|
||||
private int mArcColor;
|
||||
//圆弧的画笔的宽度
|
||||
private float mStrokeWith = getResources().getDimension(R.dimen.sweeper_ext_arcView_stroke_with);
|
||||
//文字描述的paint
|
||||
private Paint mTextPaint;
|
||||
|
||||
//当前进度夹角大小
|
||||
private float mIncludedAngle = 0;
|
||||
//当前数据
|
||||
private int currentValue;
|
||||
//最大数据
|
||||
private int maxValue = 240;
|
||||
//圆弧背景的开始和结束间的夹角大小
|
||||
private float mAngle = 270;
|
||||
//上次绘制圆弧夹角
|
||||
private float lastAngle = 0;
|
||||
|
||||
public BusArcView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public BusArcView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public BusArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
//初始化paint
|
||||
initPaint();
|
||||
//绘制弧度
|
||||
drawArc(canvas);
|
||||
//绘制文本
|
||||
drawText(canvas);
|
||||
}
|
||||
|
||||
private void drawText(Canvas canvas) {
|
||||
Rect mRect = new Rect();
|
||||
String mValue = String.valueOf(currentValue);
|
||||
mTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
|
||||
//绘制中心的数值
|
||||
mTextPaint.getTextBounds(mValue, 0, mValue.length(), mRect);
|
||||
canvas.drawText(mValue, getWidth() / 2, getHeight() / 2 + mRect.height() / 2 - 10, mTextPaint);
|
||||
|
||||
mTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
|
||||
//绘制中心文字描述
|
||||
mTextPaint.setTextSize(getResources().getDimension(R.dimen.sweeper_ext_arcView_des_text_size));
|
||||
mTextPaint.getTextBounds(mDes, 0, mDes.length(), mRect);
|
||||
canvas.drawText(mDes, getWidth() / 2, getHeight() * 17 / 20 + mRect.height() / 2, mTextPaint);
|
||||
}
|
||||
|
||||
private void drawArc(Canvas canvas) {
|
||||
//绘制圆弧背景
|
||||
RectF mRectF = new RectF(mStrokeWith, mStrokeWith, getWidth() - mStrokeWith, getHeight() - mStrokeWith);
|
||||
canvas.drawArc(mRectF, 135, mAngle, false, mArcPaint);
|
||||
|
||||
//绘制当前数值对应的圆弧
|
||||
mArcPaint.setColor(mArcColor);
|
||||
//根据当前数据绘制对应的圆弧
|
||||
canvas.drawArc(mRectF, 135, mIncludedAngle, false, mArcPaint);
|
||||
}
|
||||
|
||||
private void initPaint() {
|
||||
//圆弧的paint
|
||||
mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
//抗锯齿
|
||||
mArcPaint.setAntiAlias(true);
|
||||
mArcPaint.setColor(Color.parseColor("#151D4C"));
|
||||
//设置透明度(数值为0-255)
|
||||
mArcPaint.setAlpha(100);
|
||||
//设置画笔的画出的形状
|
||||
mArcPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||
mArcPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
//设置画笔类型
|
||||
mArcPaint.setStyle(Paint.Style.STROKE);
|
||||
//画笔宽度
|
||||
mArcPaint.setStrokeWidth(mStrokeWith);
|
||||
|
||||
//中心文字的paint
|
||||
mTextPaint = new Paint();
|
||||
mTextPaint.setAntiAlias(true);
|
||||
mTextPaint.setColor(Color.parseColor("#FFFFFF"));
|
||||
//设置文本的对齐方式
|
||||
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||
//mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.dp_12));
|
||||
mTextPaint.setTextSize(getResources().getDimension(R.dimen.sweeper_ext_arcView_center_text_size));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 为绘制弧度及数据设置动画
|
||||
*
|
||||
* @param startAngle 开始的弧度
|
||||
* @param currentAngle 需要绘制的弧度
|
||||
* @param time 动画执行的时长
|
||||
*/
|
||||
private void setAnimation(float startAngle, float currentAngle, int time) {
|
||||
//绘制当前数据对应的圆弧的动画效果
|
||||
ValueAnimator progressAnimator = ValueAnimator.ofFloat(startAngle, currentAngle);
|
||||
progressAnimator.setDuration(time);
|
||||
progressAnimator.setTarget(mIncludedAngle);
|
||||
progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
mIncludedAngle = (float) animation.getAnimatedValue();
|
||||
//重新绘制,不然不会出现效果
|
||||
postInvalidate();
|
||||
}
|
||||
});
|
||||
//开始执行动画
|
||||
progressAnimator.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置弧形颜色
|
||||
*
|
||||
* @param value 颜色值
|
||||
*/
|
||||
public void setArcColor(int value) {
|
||||
mArcColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据
|
||||
*
|
||||
* @param value 当前绘制的值
|
||||
*/
|
||||
public void setValues(int value) {
|
||||
//完全覆盖
|
||||
if (value > maxValue) {
|
||||
value = maxValue;
|
||||
}
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
currentValue = value;
|
||||
//计算弧度比重
|
||||
float scale = (float) currentValue / maxValue;
|
||||
//计算弧度
|
||||
float currentAngle = scale * mAngle;
|
||||
//开始执行动画
|
||||
setAnimation(lastAngle, currentAngle, 1000);
|
||||
lastAngle = currentAngle;
|
||||
//重新绘制
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
|
||||
private float dp2px(float dp) {
|
||||
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
|
||||
return dp * metrics.density;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.mogo.och.sweepercloud.view
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
/**
|
||||
* 倒计时View
|
||||
*/
|
||||
class CountDownView : AppCompatTextView, Handler.Callback {
|
||||
private val mHandler = Handler(this)
|
||||
private var mCountDownTime = DEFAULT_COUNT_DOWN_TIME
|
||||
private var listener: CountDownListener? = null
|
||||
|
||||
constructor(context: Context?) : super(context!!) {}
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs) {}
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context!!, attrs, defStyleAttr) {}
|
||||
|
||||
override fun handleMessage(message: Message): Boolean {
|
||||
if (message.what == MSG_COUNT_DOWN) {
|
||||
mCountDownTime--
|
||||
if (mCountDownTime > 0) {
|
||||
text = "$mCountDownTime"
|
||||
mHandler.sendEmptyMessageDelayed(MSG_COUNT_DOWN, DEFAULT_COUNT_DOWN_DELAY)
|
||||
} else {
|
||||
stopCountDown()
|
||||
listener?.stop()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun setCountDownListener(listener: CountDownListener?) {
|
||||
this.listener = listener
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动倒计时
|
||||
*/
|
||||
fun startCountDown(countDownTime:Int) {
|
||||
mHandler.removeMessages(MSG_COUNT_DOWN)
|
||||
text = "$countDownTime"
|
||||
mCountDownTime=countDownTime
|
||||
mHandler.sendEmptyMessageDelayed(MSG_COUNT_DOWN, DEFAULT_COUNT_DOWN_DELAY)
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止倒计时
|
||||
*/
|
||||
fun stopCountDown() {
|
||||
mHandler.removeMessages(MSG_COUNT_DOWN)
|
||||
text = null
|
||||
}
|
||||
|
||||
interface CountDownListener {
|
||||
fun stop()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_COUNT_DOWN_TIME = 15
|
||||
private const val MSG_COUNT_DOWN = 1001
|
||||
private const val DEFAULT_COUNT_DOWN_DELAY = 1000L
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
package com.mogo.och.sweepercloud.view;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.och.sweepercloud.R;
|
||||
|
||||
/**
|
||||
* 滑块滑动面板
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SlidePanelView extends View {
|
||||
private static final String TAG = "SlidePanelView";
|
||||
|
||||
public SlidePanelView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SlidePanelView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SlidePanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.SlidePanelView);
|
||||
textSize = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_textSize, textSize);
|
||||
BLOCK_START_X = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_BLOCK_START_X, BLOCK_START_X);
|
||||
BLOCK_START_Y = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_BLOCK_START_Y, BLOCK_START_Y);
|
||||
NORMAL_TEXT_MARGIN_LEFT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_LEFT, NORMAL_TEXT_MARGIN_LEFT);
|
||||
NORMAL_TEXT_MARGIN_RIGHT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_RIGHT, NORMAL_TEXT_MARGIN_RIGHT);
|
||||
SHORT_TEXT_MARGIN_LEFT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_LEFT, SHORT_TEXT_MARGIN_LEFT);
|
||||
SHORT_TEXT_MARGIN_RIGHT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_RIGHT, SHORT_TEXT_MARGIN_RIGHT);
|
||||
init();
|
||||
}
|
||||
|
||||
private final Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint blockPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private static int textSize = 40;
|
||||
private static int BLOCK_START_X = 15;
|
||||
private static int BLOCK_START_Y = 15;
|
||||
private static int NORMAL_TEXT_MARGIN_LEFT = 40;
|
||||
private static int NORMAL_TEXT_MARGIN_RIGHT = 60;
|
||||
private static int SHORT_TEXT_MARGIN_LEFT = 60;
|
||||
private static int SHORT_TEXT_MARGIN_RIGHT = 70;
|
||||
|
||||
private int textMarginLeft = NORMAL_TEXT_MARGIN_LEFT;
|
||||
private int textMarginRight = NORMAL_TEXT_MARGIN_RIGHT;
|
||||
|
||||
private OnSlidePanelMoveToEndListener moveToEndListener;
|
||||
|
||||
private int blockWidth = 0;
|
||||
private int blockOffset = 0;
|
||||
|
||||
private float lastX;
|
||||
private boolean isToEnd = false;
|
||||
|
||||
private static final String STRING_SLIDE_TO_RIGHT = "向右滑动";
|
||||
private RectF bgRectF;
|
||||
private Bitmap bmBlock;
|
||||
|
||||
private final Matrix gradientMatrix = new Matrix();
|
||||
private float matrixTranslate;
|
||||
private final Rect textRect = new Rect();
|
||||
private LinearGradient textGradient;
|
||||
|
||||
private ObjectAnimator matrixAnim;
|
||||
|
||||
private String blockText = STRING_SLIDE_TO_RIGHT;
|
||||
private Paint.FontMetrics blockTextMetrics = new Paint.FontMetrics();
|
||||
|
||||
private static final int GRADIENT_OFFSET = 200;
|
||||
|
||||
public void setOnSlidePanelMoveToEndListener(OnSlidePanelMoveToEndListener moveToEndListener) {
|
||||
this.moveToEndListener = moveToEndListener;
|
||||
}
|
||||
|
||||
private void setBlockOffset(int blockOffset) {
|
||||
this.blockOffset = blockOffset;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void setMatrixTranslate(float matrixTranslate) {
|
||||
this.matrixTranslate = matrixTranslate;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.blockText = text;
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
bgRectF = new RectF(0, 0, 0, 0);
|
||||
bgPaint.setColor(Color.parseColor("#CC0F1325"));
|
||||
bgPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
textPaint.setStyle(Paint.Style.FILL);
|
||||
textPaint.setTextSize(textSize);
|
||||
textPaint.setTextAlign(Paint.Align.LEFT);
|
||||
textGradient = new LinearGradient(-GRADIENT_OFFSET, 0, 0, 0, new int[]{0x33ffffff, 0xffffffff, 0x33ffffff}, null, Shader.TileMode.CLAMP);
|
||||
textGradient.setLocalMatrix(gradientMatrix);
|
||||
textPaint.setShader(textGradient);
|
||||
textPaint.getFontMetrics(blockTextMetrics);
|
||||
|
||||
bmBlock = BitmapFactory.decodeResource(getResources(), R.drawable.sweeper_base_slide_block);
|
||||
blockWidth = bmBlock.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int widthSize;
|
||||
int heightSize;
|
||||
|
||||
if (blockText.length() < 5) {
|
||||
textMarginLeft = SHORT_TEXT_MARGIN_LEFT;
|
||||
textMarginRight = SHORT_TEXT_MARGIN_RIGHT;
|
||||
} else {
|
||||
textMarginLeft = NORMAL_TEXT_MARGIN_LEFT;
|
||||
textMarginRight = NORMAL_TEXT_MARGIN_RIGHT;
|
||||
}
|
||||
|
||||
if (widthMode == MeasureSpec.AT_MOST) {
|
||||
// 宽度根据图片大小,字符串长度,各种间隔确定
|
||||
// 高度根据图片大小和上下间隔确定
|
||||
textPaint.getTextBounds(blockText, 0, blockText.length(), textRect);
|
||||
widthSize = BLOCK_START_X * 2 + bmBlock.getWidth() + textMarginLeft + textMarginRight + textRect.width();
|
||||
heightSize = BLOCK_START_Y * 2 + bmBlock.getHeight();
|
||||
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
|
||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
|
||||
}
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private float textOffset = 0;
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (bgRectF != null){
|
||||
bgRectF.left = 0;
|
||||
bgRectF.top = 0;
|
||||
bgRectF.right = w;
|
||||
bgRectF.bottom = h;
|
||||
}
|
||||
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.cancel();
|
||||
}
|
||||
textOffset = (getHeight() - blockTextMetrics.ascent - blockTextMetrics.descent) / 2;
|
||||
matrixAnim = ObjectAnimator.ofFloat(this, "matrixTranslate", 0, w + GRADIENT_OFFSET).setDuration(2000);
|
||||
matrixAnim.setRepeatCount(ValueAnimator.INFINITE);
|
||||
matrixAnim.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (x > BLOCK_START_X + blockOffset && x < blockWidth + BLOCK_START_X + blockOffset && y > BLOCK_START_Y && y < getHeight() - BLOCK_START_Y) {
|
||||
isToEnd = false;
|
||||
lastX = x;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (lastX != 0) {
|
||||
blockOffset = (int) (x - lastX);
|
||||
if (blockOffset < 0) {
|
||||
blockOffset = 0;
|
||||
}
|
||||
if (blockOffset + BLOCK_START_X + blockWidth > getWidth()) {
|
||||
// 超出右边界
|
||||
blockOffset = getWidth() - BLOCK_START_X - blockWidth;
|
||||
if (!isToEnd) {
|
||||
isToEnd = true;
|
||||
if (moveToEndListener != null) {
|
||||
moveToEndListener.moveToEnd();
|
||||
}
|
||||
startBlockBackAnim();
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
// 执行滑块回归动画
|
||||
if (!isToEnd) {
|
||||
startBlockBackAnim();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void startBlockBackAnim() {
|
||||
ObjectAnimator blockBackanimator = ObjectAnimator.ofInt(this, "blockOffset", blockOffset, 0);
|
||||
blockBackanimator.setInterpolator(new DecelerateInterpolator());
|
||||
blockBackanimator.setDuration(1000 * blockOffset / getWidth());
|
||||
blockBackanimator.start();
|
||||
lastX = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
// 画背景
|
||||
canvas.drawRoundRect(bgRectF, (float) getHeight() / 2, (float) getHeight() / 2, bgPaint);
|
||||
// 画文字
|
||||
gradientMatrix.setTranslate(matrixTranslate, 0);
|
||||
textGradient.setLocalMatrix(gradientMatrix);
|
||||
canvas.save();
|
||||
canvas.drawText(blockText, blockWidth + BLOCK_START_X + textMarginLeft, textOffset, textPaint);
|
||||
canvas.restore();
|
||||
// 画滑块
|
||||
canvas.drawBitmap(bmBlock, BLOCK_START_X + blockOffset, BLOCK_START_Y, blockPaint);
|
||||
}
|
||||
|
||||
public interface OnSlidePanelMoveToEndListener {
|
||||
/**
|
||||
* 滑块滑到了末尾
|
||||
*/
|
||||
void moveToEnd();
|
||||
}
|
||||
}
|
||||
BIN
OCH/sweeper/sweeper-cloud/src/main/res/drawable-xhdpi/sweeper_cloud_rotate.png
Executable file
BIN
OCH/sweeper/sweeper-cloud/src/main/res/drawable-xhdpi/sweeper_cloud_rotate.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<gradient android:startColor="#2A537F" android:endColor="#263A5B" android:angle="135"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:innerRadiusRatio="3"
|
||||
android:shape="ring"
|
||||
android:thicknessRatio="10"
|
||||
android:useLevel="false">
|
||||
<gradient
|
||||
android:endColor="#6020AAFF"
|
||||
android:centerColor="#102F6EFF"
|
||||
android:startColor="#6020AAFF"
|
||||
android:type="sweep" />
|
||||
</shape>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="false" android:drawable="@drawable/sweeper_task_list_not_selected"/>
|
||||
<item android:state_selected="true" android:drawable="@drawable/sweeper_task_list_selected"/>
|
||||
</selector>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#4D2F6EFF"/>
|
||||
<corners
|
||||
android:bottomRightRadius="30dp" android:bottomLeftRadius="@dimen/dp_30"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.och.common.module.wigets.OCHRoundConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/dp_800"
|
||||
android:layout_height="@dimen/dp_560"
|
||||
android:background="@drawable/bg_shape_dialog_cloud_view"
|
||||
app:roundLayoutRadius="@dimen/dp_45"
|
||||
android:layout_gravity="center">
|
||||
<ImageView
|
||||
android:id="@+id/sweeper_cloud_imageview"
|
||||
android:layout_width="@dimen/dp_70"
|
||||
android:layout_height="@dimen/dp_70"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginTop="@dimen/dp_30"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:src="@drawable/shape_sweeper_cloud_rotation"
|
||||
/>
|
||||
<com.mogo.och.sweepercloud.view.CountDownView
|
||||
android:id="@+id/sweeper_cloud_countdown"
|
||||
android:layout_width="@dimen/dp_65"
|
||||
android:layout_height="@dimen/dp_65"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginTop="@dimen/dp_30"
|
||||
android:text="15"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/dp_32"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_30"
|
||||
android:gravity="center"
|
||||
android:text="任务领取"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/dp_56"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginTop="@dimen/dp_49"
|
||||
android:layout_marginEnd="@dimen/dp_30"
|
||||
android:gravity="center"
|
||||
android:text="请确认是否接取任务AAAAAAA"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="@dimen/dp_50"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sweeper_cloud_title"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_tip"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:layout_marginEnd="@dimen/dp_30"
|
||||
android:gravity="center"
|
||||
android:text="(任务时间09:00-12:00)"
|
||||
android:textColor="#A6CEFF"
|
||||
android:textSize="@dimen/dp_40"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sweeper_cloud_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_134"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_left"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_shape_left_bottom_round"
|
||||
android:gravity="center"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="@dimen/dp_50"
|
||||
tools:text="确认" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_middle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="#3769B5"
|
||||
android:gravity="center"
|
||||
android:text="下一个"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="@dimen/dp_50" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sweeper_cloud_right"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="134dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_shape_right_bottom_round"
|
||||
android:gravity="center"
|
||||
android:text="拒绝"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="@dimen/dp_50" />
|
||||
</LinearLayout>
|
||||
</com.mogo.och.common.module.wigets.OCHRoundConstraintLayout>
|
||||
Reference in New Issue
Block a user