bg_ambient_lighting_bubble
bg_ambient_lighting_bubble_border
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by fengjunjia on 2020/6/24.
* 自定义氛围灯选择控件
*/
public class AmbientLightingView extends View {
private Context mContext;
private int mViewWidth; // 视图实际宽度
private int mViewHeight; // 视图实际高度
private int mViewLeftBlank; // 给气泡控件左右预留空白区域
private int mViewRightBlank;
private int mBubblePointLeft; // 当前气泡左上角位置
private String mSelectColor = "蓝";
private int mSingleColorWidth; // 单条颜色所占宽度
private Bitmap mLightingBitmap; // 灯带位图
private Paint mLightingPaint; // 灯带画笔
private Bitmap mBubbleBitmap; // 气泡位图
private Paint mBubblePaint; // 气泡画笔
private Bitmap mBubbleBorderBitmap;// 气泡边框图层
private OnPositionChangeListener mOnPositonChangeListener = null;
private int mBubbleColor = -16755457;
private int drawablePixelX = 0;// 图片色值的X坐标
public void setOnPositionChangeListener(OnPositionChangeListener mOnPositionChangeListener) {
this.mOnPositonChangeListener = mOnPositionChangeListener;
}
// TODO: 2020/6/24 预留回调接口,待氛围灯参数确定后完善
public interface OnPositionChangeListener {
void onPositionChanged();
void onStartTrackingTouch();
void onStopTrackingTouch();
}
public AmbientLightingView(Context context) {
super(context);
this.mContext = context;
init(context);
}
public AmbientLightingView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
init(context);
}
public AmbientLightingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
init(context);
}
private void init(Context context) {
mViewLeftBlank = DisplayUtils.dp2px(mContext, 23);
mViewRightBlank = DisplayUtils.dp2px(mContext, 23);
mSingleColorWidth = DisplayUtils.dp2px(mContext, 9);
mLightingPaint = new Paint();
mLightingPaint.setAntiAlias(true);
mBubblePaint = new Paint();
mBubblePaint.setAntiAlias(true);
mBubblePaint.setStrokeCap(Paint.Cap.ROUND);
mBubblePaint.setTextAlign(Paint.Align.CENTER);
mBubblePaint.setFakeBoldText(true);
mBubblePaint.setTextSize(DisplayUtils.sp2px(mContext, 23));
mBubblePaint.setColor(ContextCompat.getColor(mContext, R.color.tv_setting_bubble_text));
mBubblePaint.setTextAlign(Paint.Align.CENTER);
setFocusable(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mViewWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mViewHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
mLightingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting);
mBubbleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting_bubble);
mBubbleBorderBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting_bubble_border);
if (null != mLightingBitmap) {
getCurrentColor(mBubblePointLeft);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
seekTo(eventX, eventY);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBubbleBitmap == null) {
mBubbleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting_bubble);
}
if (mBubbleBorderBitmap == null) {
mBubbleBorderBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting_bubble_border);
}
if (mLightingBitmap == null) {
mLightingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_ambient_lighting);
}
canvas.drawBitmap(mLightingBitmap, mViewLeftBlank, DisplayUtils.dp2px(mContext, 35), mLightingPaint);
RectF rect = new RectF();
rect.left = mBubblePointLeft;
rect.top = 0;
rect.right = mBubblePointLeft + mBubbleBitmap.getWidth();
rect.bottom = mBubbleBitmap.getHeight();
int saved = 0;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
saved = canvas.saveLayer(rect, mBubblePaint);
}
canvas.drawBitmap(mBubbleBitmap, mBubblePointLeft, 0, mBubblePaint);// 先绘制目标文件 ----第一层
mBubblePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 设置模式
mBubblePaint.setColor(mBubbleColor);
canvas.drawRect(rect, mBubblePaint);// 绘制源文件 -----第二层
canvas.save();
mBubblePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));// 设置模式
mBubblePaint.setColor(mBubbleColor);
canvas.drawBitmap(mBubbleBorderBitmap, mBubblePointLeft, 0, mBubblePaint);// ---- 第三层
//清除混合模式
mBubblePaint.setXfermode(null);
//还原画布
canvas.restoreToCount(saved);
// canvas.drawText(mSelectColor, mBubblePointLeft + DisplayUtils.dp2px(mContext, 23), DisplayUtils.dp2px(mContext, 25), mBubblePaint);
}
/**
* 拖拽移动色值
*/
private void seekTo(float eventX, float eventY) {
int x = (int) eventX;
mSelectColor = getColorStr(x);
if (x < mViewLeftBlank) {
mBubblePointLeft = 0;
} else if (x > mViewWidth - mViewRightBlank) {
mBubblePointLeft = mViewWidth - mViewRightBlank - DisplayUtils.dp2px(mContext, 23);
} else {
mBubblePointLeft = x - DisplayUtils.dp2px(mContext, 23);
}
// 获取当前颜色值
getCurrentColor(mBubblePointLeft);
invalidate();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (null != mLightingBitmap) {
mLightingBitmap.recycle();
mLightingBitmap = null;
}
if (null != mBubbleBitmap) {
mBubbleBitmap.recycle();
mBubbleBitmap = null;
}
}
// 防止父类响应事件
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
getParent().requestDisallowInterceptTouchEvent(true);
return super.dispatchTouchEvent(event);
}
private String getColorStr(int touchEventX) {
if (touchEventX < mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 5)) {
return "蓝";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 10)) {
return "紫";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 19)) {
return "粉";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 24)) {
return "红";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 30)) {
return "橙";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 36)) {
return "黄";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 47)) {
return "绿";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 52)) {
return "青";
} else if (touchEventX <= mViewLeftBlank + DisplayUtils.dp2px(mContext, mSingleColorWidth * 63)) {
return "蓝";
} else {
return "白";
}
}
/**
* 设置当前进度条位置
*
* @param progress
*/
public void setCurrentColorProgress(int progress) {
if (progress <= 0) {
mBubblePointLeft = 0;
} else if (progress > 100) {
mBubblePointLeft = mViewWidth - mViewRightBlank - DisplayUtils.dp2px(mContext, 23);
} else {
mBubblePointLeft = progress * mLightingBitmap.getWidth() - DisplayUtils.dp2px(mContext, 23);
}
getCurrentColor(mBubblePointLeft);
invalidate();
}
/**
* 获取当前色值
*
* @param bubblePointLeft
*/
private void getCurrentColor(int bubblePointLeft) {
// 获取当前颜色值
if (bubblePointLeft >= 0 && bubblePointLeft < mLightingBitmap.getWidth()) {
drawablePixelX = bubblePointLeft;
} else if (bubblePointLeft == mLightingBitmap.getWidth()) {
drawablePixelX = mLightingBitmap.getWidth() - 1;
}
if (drawablePixelX >= 0 && drawablePixelX < mLightingBitmap.getWidth()) {
mBubbleColor = mLightingBitmap.getPixel((int) drawablePixelX, 24);
}
}
}