自定义输入框
效果:

代码
@SuppressLint("AppCompatCustomView")
public class CleanTextView extends EditText implements View.OnFocusChangeListener, TextWatcher {
private Drawable compoundDrawable;
//控制是否获取焦点
private boolean isFous;
public CleanTextView(Context context) {
super(context);
}
public CleanTextView(Context context, AttributeSet attrs) {
this(context,attrs,R.attr.editTextStyle);
}
public CleanTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//获取textView上下左右四个图片的位子
Drawable[] compoundDrawables = getCompoundDrawables();
//获取右面图片的位子
compoundDrawable = compoundDrawables[2];
if (compoundDrawable == null){
//加载本地图片
compoundDrawable = getResources().getDrawable(R.mipmap.ppp);
}
//确定图片的位子
compoundDrawable.setBounds(0,0,compoundDrawable.getIntrinsicWidth(),compoundDrawable.getIntrinsicHeight());
//初始化监听 焦点事件监听
setOnFocusChangeListener(this);
//字体监听
addTextChangedListener(this);
//控制图片显隐
setCompoundIconVisibly(false);
}
private void setCompoundIconVisibly(boolean isvisibly) {
Drawable drawable = isvisibly ? compoundDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1],drawable,getCompoundDrawables()[3]);
}
@Override
public void onFocusChange(View v, boolean isFous) {
//焦点
this.isFous = isFous;
if (!isFous){
setCompoundIconVisibly(false);
}else if (this.getText().toString().length() > 0){
setCompoundIconVisibly(true);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//监听字体改变
if (s.length() > 0 && isFous){
setCompoundIconVisibly(true);
}else{
setCompoundIconVisibly(false);
}
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_UP:
boolean b = (event.getX() > getWidth() - getTotalPaddingRight()) && (event.getX() < getWidth() - getPaddingRight());
if (b){
this.setText("");
}
break;
}
return super.onTouchEvent(event);
}}
时钟
效果:

代码
public class My_TimeView extends View {
private int width;
private int height;
private Paint mPaintLine;
private Paint mPaintCircle;
private Paint mPaintHour;
private Paint mPaintMinute;
private Paint mPaintSec;
private Paint mPaintText;
private Calendar mCalendar;
public static final int NEED_INVALIDATE = 0X23;
//每隔一秒,在handler中调用一次重新绘制方法
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case NEED_INVALIDATE:
mCalendar = Calendar.getInstance();
invalidate();//告诉UI主线程重新绘制
handler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);
break;
default:
break;
}
}
};
public My_TimeView(Context context) {
super(context);
}
public My_TimeView(Context context, AttributeSet attrs) {
super(context, attrs);
mCalendar = Calendar.getInstance();
mPaintLine = new Paint();
mPaintLine.setColor(Color.BLUE);
mPaintLine.setStrokeWidth(10);
mPaintCircle = new Paint();
mPaintCircle.setColor(Color.GREEN);//设置颜色
mPaintCircle.setStrokeWidth(10);//设置线宽
mPaintCircle.setAntiAlias(true);//设置是否抗锯齿
mPaintCircle.setStyle(Paint.Style.STROKE);//设置绘制风格
mPaintText = new Paint();
mPaintText.setColor(Color.BLUE);
mPaintText.setStrokeWidth(10);
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setTextSize(40);
mPaintHour = new Paint();
mPaintHour.setStrokeWidth(8);
mPaintHour.setAntiAlias(true);
mPaintHour.setColor(Color.RED);
mPaintMinute = new Paint();
mPaintMinute.setStrokeWidth(8);
mPaintHour.setAntiAlias(true);
mPaintMinute.setColor(Color.YELLOW);
mPaintSec = new Paint();
mPaintSec.setStrokeWidth(8);
mPaintHour.setAntiAlias(true);
mPaintSec.setColor(Color.BLUE);
handler.sendEmptyMessage(NEED_INVALIDATE);//向handler发送一个消息,让它开启重绘
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int circleRadius = 330;
//画出大圆
canvas.drawCircle(width / 2, height / 2, circleRadius, mPaintCircle);
//画出圆中心
canvas.drawCircle(width / 2, height / 2, 20, mPaintCircle);
//依次旋转画布,画出每个刻度和对应数字
for (int i = 1; i <= 12; i++) {
canvas.save();//保存当前画布
canvas.rotate(360 / 12 * i, width / 2, height / 2);
//左起:起始位置x坐标,起始位置y坐标,终止位置x坐标,终止位置y坐标,画笔(一个Paint对象)
canvas.drawLine(width / 2, height / 2 - circleRadius, width / 2, height / 2 - circleRadius + 30, mPaintCircle);
//左起:文本内容,起始位置x坐标,起始位置y坐标,画笔
canvas.drawText(String.valueOf(i), width / 2, height / 2 - circleRadius + 70, mPaintText);
canvas.restore();//
}
int minute = mCalendar.get(Calendar.MINUTE);//得到当前分钟数
int hour = mCalendar.get(Calendar.HOUR);//得到当前小时数
int sec = mCalendar.get(Calendar.SECOND);//得到当前秒数
float minuteDegree = minute / 60f * 360;//得到分针旋转的角度
canvas.save();
canvas.rotate(minuteDegree, width / 2, height / 2);
canvas.drawLine(width / 2, height / 2 - 250, width / 2, height / 2 + 40, mPaintMinute);
canvas.restore();
float hourDegree = (hour * 60 + minute) / 12f / 60 * 360;//得到时钟旋转的角度
canvas.save();
canvas.rotate(hourDegree, width / 2, height / 2);
canvas.drawLine(width / 2, height / 2 - 200, width / 2, height / 2 + 30, mPaintHour);
canvas.restore();
float secDegree = sec / 60f * 360;//得到秒针旋转的角度
canvas.save();
canvas.rotate(secDegree, width / 2, height / 2);
canvas.drawLine(width / 2, height / 2 - 300, width / 2, height / 2 + 40, mPaintSec);
canvas.restore();
}}
柱状图
效果

代码
public class My_ZhuView extends View {
private String[] xData = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
private String[] yData = {"100","200","300","400","500","600","700","800","900","1000",};
private List<Integer> list = Arrays.asList(300,200,520,130,750,846,210);
private int margin = 20;
private int marginX = 30;
private int marginY = 30;
private int pointX;
private int pointY;
private int scaleX;
private int scaleY;
private Paint paintXY;
private Paint paintRect;
private Paint paintValue;
public My_ZhuView(Context context) {
super(context,null);
}
public My_ZhuView(Context context, AttributeSet attrs) {
super(context, attrs,0);
}
public My_ZhuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void initView(String[] xData,String[] yData,List<Integer> list){
this.xData = xData;
this.yData = yData;
this.list = list;
}
private void init(){
pointX = margin+marginX;
pointY = getHeight() - (margin+marginY);
scaleX = (getHeight() - 2 * margin-marginX) / xData.length;
scaleY = (getHeight()-2*margin-marginY)/yData.length;
paintXY = new Paint();
paintXY.setStyle(Paint.Style.STROKE);
paintXY.setAntiAlias(true);
paintXY.setDither(true);
paintXY.setColor(Color.BLACK);
paintXY.setStrokeWidth(3);
paintRect = new Paint();
paintRect.setStyle(Paint.Style.STROKE);
paintRect.setAntiAlias(true);
paintRect.setDither(true);
paintRect.setColor(Color.BLACK);
paintRect.setStrokeWidth(15);
paintValue = new Paint();
paintValue.setStyle(Paint.Style.FILL);
paintValue.setAntiAlias(true);
paintValue.setDither(true);
paintValue.setStrokeWidth(1);
}
@Override
protected void onDraw(Canvas canvas) {
init();
canvas.drawLine(pointX,pointY,getWidth()-margin,pointY,paintXY);
canvas.drawLine(pointX,pointY,pointX,margin,paintXY);
for (int i = 1; i < xData.length; i++) {
int height = pointY - margin;
float single = height / Integer.valueOf(yData[yData.length-1]);
int marginLeft = pointX + scaleX * i;
canvas.drawText(xData[i-1],marginLeft-53,pointY+25,paintValue);
RectF rectF = new RectF(marginLeft-50,height-(list.get(i-1)*single),marginLeft-10,pointY);
canvas.drawRect(rectF,paintRect);
canvas.drawText(list.get(i-1)+"",marginLeft - 43,height-(list.get(i-1)*single)-10,paintValue);
}
for (int i = 1; i < yData.length; i++) {
int marginTop = scaleY * i;
canvas.drawText(yData[i-1],pointX,pointY-marginTop,paintValue);
}
}}