思路:随机生成几个字符,绘制字符,加干扰线或者是一些其他的图形,为了美观,需要绘制一下背景,或者边框。保存该Bitmap对象,就可以使用了。见代码
public class BitmapCode {
private static final char[] CHARS = {
'0','1', '2', '3', '4', '5', '6', '7', '8', '9'
};
private static BitmapCode bmpCode;
public static BitmapCode getInstance() {
if(bmpCode == null)
bmpCode = new BitmapCode();
return bmpCode;
}
private final static int DEFAULT_WIDTH=100;//图片的宽
private final static int DEFAULT_HEIGHT=40;//图片的高度
private final static int CODE_LENGTH=4;//验证码的长度
private int width=DEFAULT_WIDTH;
private int height=DEFAULT_HEIGHT;
private int codeLength=CODE_LENGTH;
private int lineNum=10;
private Random random=new Random();
private String code;
public Bitmap createBitmap(){
createCode();
Bitmap bp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(bp);
canvas.drawColor(Color.rgb(241,252,243));//绘制背景色
Rect rect=new Rect(0,0,width,height);
//绘制边框
{
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawRect(rect, paint);
}
//绘制随机验证码
{
Paint textPaint=new Paint();
textPaint.setTextSize(24);
textPaint.setColor(Color.BLUE);
//测量字体宽度
float textWidth=textPaint.measureText("0");
//测量字体高度
float textHeight=textPaint.ascent()+textPaint.descent();
//离顶部的标准距离
float paddingTop=(height-textHeight)/2;
//离左侧的标准距离
float paddingLeft=(width/4f-textWidth)/2;
for(int i=0;i<code.length();i++){
float skewX = random.nextInt(12) / 10;
skewX = random.nextBoolean() ? skewX : -skewX;
textPaint.setTextSkewX(skewX); //float类型参数,负数表示右斜,整数左斜 canvas.drawText(code.charAt(i)+"",paddingLeft+i*width/4,paddingTop+random.nextInt(10)-5,textPaint);//让字体倾斜,垂直位置离中间位置随机偏移
}
}
//绘制干扰线条
{
Paint linePaint = new Paint();
drawLine(canvas, linePaint);
}
canvas.save(Canvas.ALL_SAVE_FLAG );
canvas.restore();
return bp;
}
/**
* 生成随机验证码
* @return
*/
private void createCode(){
StringBuilder builder=new StringBuilder();
for(int i=0;i<codeLength;i++) {
builder.append(CHARS[random.nextInt(CHARS.length)]);
}
this.code=builder.toString();
}
//利用此方法返回生成的字符,供与用户的输入进行核对
public String getCode(){
return this.code;
}
private void drawLine(Canvas canvas,Paint paint){
for(int i=0;i<lineNum;i++){
paint.setColor(randomColor());
int startX=random.nextInt(width);
int startY=random.nextInt(height);
int endX=random.nextInt(width);
int endY=random.nextInt(height);
canvas.drawLine(startX,startY,endX,endY,paint);
}
}
//生成随机颜色
private int randomColor(){
int red=random.nextInt(256);
int green=random.nextInt(256);
int blue=random.nextInt(256);
return Color.rgb(red,green,blue);
}
}
以上类可以作为工具类使用,接下来就是使用了,我的注册页面是在Fragment中:
public class RegisterFragment1 extends Fragment {
private TextView land;
private TextView register;
private ImageView code;//验证码ImageView
private EditText phone;
private EditText checkCode;
private BitmapCode bitmapCode=BitmapCode.getInstance();//此处得到BitmapCode对象
private RegisterCallBack mCallBack=null;
private PopupWindow popupWindow;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root=inflater.inflate(R.layout.register_frag1,null);
land=(TextView) root.findViewById(R.id.tv_land);
register=(TextView) root.findViewById(R.id.tv_register);
code=(ImageView) root.findViewById(R.id.iv_code);
phone=(EditText) root.findViewById(R.id.et_phone);
checkCode=(EditText) root.findViewById(R.id.et_check_code);
/**通过createBitmap()方法生成图形验证码*/
code.setImageBitmap(bitmapCode.createBitmap());
code.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击ImageView,通过createBitmap生成新图片
code.setImageBitmap(bitmapCode.createBitmap());
}
});
land.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RegisterFragment1.this.getActivity().finish();
Intent intent=new Intent( RegisterFragment1.this.getActivity(),LandActivity.class);
startActivity(intent);
}
});
/**注册按钮的点击事件,根据bitmapCode.getCode()得到实际生成的验证码与用户的输入进行比对*/
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(phone.getText().toString().length()!=11){
mCallBack.show("请输入正确的手机号码");
}else if(!checkCode.getText().toString().equals(bitmapCode.getCode())){
mCallBack.show("验证码输入错误");
}else if(mCallBack!=null)
mCallBack.toNext(phone.getText().toString());
}
});
return root;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.mCallBack=(RegisterCallBack) context;
}
}
我的注册页面效果如下