关键字
自定义View
调色板
摘要:
通过
布局代码
和java代码
结合的方式,来自定义视图,构建一个环形调色板;
效果图
思路:
虽然可以通过继承view的方式同时实现布局和触摸效果,
但是如果通过xml布局代码控制视图显示 + java代码控制触摸效果将会更简单;布局:借助两张同样大小的透明图片(彩色圆环、中间部分),
并在最里层放置一个含背景颜色ImageView
,来动态设置触摸处对应的颜色值;通过LayoutInflater加载xml文件,并添加给自己;
LayoutInflater.from(context).inflate(R.layout.view_color_picker, this, true);
自定义的View继承自FrameLayout,并通过LayoutInflater加载以merge为根布局的xml文件;
只对最外层的
ImageView
添加触摸事件;过滤颜色值为0的部分,这样的话触摸到空白的地方就不会改变颜色了(即只在有颜色的地方允许触摸);
添加变化的监听接口
OnColorChangeListener
根据触摸点的位置来获取对应点颜色值(使用
bitmap.getPixel(x, y)
的方式获取);
用法
private void initView() {
ColorPickerLayout cpv = (ColorPickerLayout) findViewById(R.id.cpv_simple_light);
if (cpv != null) {
cpv.setOnColorChangeListener(new ColorPickerLayout.OnColorChangeListener() {
@Override
public void doColor(int color) {
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
Log.i(TAG, "当前颜色 color=" + color + " 对应rgb值:r=" + r + " g=" + g + " b=" + b);
}
});
}
}
源码
public class ColorPickerLayout extends FrameLayout {
public interface OnColorChangeListener {
void doColor(int color);
}
public void setOnColorChangeListener(OnColorChangeListener listener) {
mOnColorChangeListener = listener;
}
private OnColorChangeListener mOnColorChangeListener;
public ColorPickerLayout(Context context) {
this(context, null);
}
public ColorPickerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setUp(context);
}
private void setUp(Context context) {
// 从布局中加载并添加给自己
View view = LayoutInflater.from(context).inflate(R.layout.view_color_picker, this, true);
final ImageView ivIndicator = (ImageView) view.findViewById(R.id.iv_picker_indicator);
final ImageView ivPointerBg = (ImageView) view.findViewById(R.id.iv_pointer_bg);
final ImageView ivBg = (ImageView) view.findViewById(R.id.iv_picker_bg);
final Bitmap bgBitmap = Uimg.getBitmap(ivBg);
// 给外层的ivBg设置触摸监听
ivBg.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
int color = 0;
if (x >= 0 && y >= 0 && x < bgBitmap.getWidth() && y < bgBitmap.getHeight()) {
color = bgBitmap.getPixel(x, y);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
if (color != 0) {
changePointerBgColor(ivPointerBg, color);
changeIndicatorPosition(ivIndicator, x, y);
}
}
return true;
}
});
}
// 改变触摸点位置
private void changeIndicatorPosition(ImageView ivIndicator, int x, int y) {
MarginLayoutParams layoutParams = (MarginLayoutParams) ivIndicator.getLayoutParams();
layoutParams.leftMargin = x - ivIndicator.getWidth() / 2;
layoutParams.topMargin = y - ivIndicator.getHeight() / 2;
ivIndicator.requestLayout();
if (ivIndicator.getVisibility() != VISIBLE) {
ivIndicator.setVisibility(VISIBLE);
}
}
// 改变触摸指示器颜色
private void changePointerBgColor(ImageView iv, int color) {
iv.setBackgroundColor(color);
if (mOnColorChangeListener != null) {
mOnColorChangeListener.doColor(color);
}
}
}