样式图:
自定义dialog的布局文件layout_code_dialog.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="180dp" android:layout_height="90dp" android:layout_gravity="center" android:background="@drawable/code_view_bg_shape" android:orientation="vertical" android:paddingTop="5dp"> <EditText android:cursorVisible="false" android:id="@+id/edt_code_input" android:layout_width="80dp" android:gravity="center" android:layout_height="40dp" android:layout_marginTop="2dp" android:layout_marginLeft="10dp" android:background="@drawable/code_view_input_bg_shape" /> <mchenys.net.csdn.blog.pcbaby_v8_testdemo.view.CodeView android:id="@+id/code_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/edt_code_input" android:layout_marginLeft="10dp" android:layout_marginBottom="5dp" android:layout_marginRight="5dp" android:layout_toRightOf="@+id/edt_code_input" /> <TextView android:id="@+id/tv_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/code_view" android:layout_below="@+id/code_view" android:text="点击图片更换" android:textSize="10sp" /> <View android:id="@+id/view_line" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/edt_code_input" android:layout_marginTop="5dp" android:background="#66666666" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/view_line"> <Button android:id="@+id/btn_cancle" android:textSize="15sp" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@android:color/transparent" android:gravity="center" android:text="取消" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#66666666" /> <Button android:id="@+id/btn_sure" android:textSize="15sp" android:textColor="#029AFF" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@android:color/transparent" android:gravity="center" android:text="确定" /> </LinearLayout> </RelativeLayout>
分别为:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#fff" /> <corners android:radius="10dp" /> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="1dp" android:color="#66666666" /> </shape>
package mchenys.net.csdn.blog.pcbaby_v8_testdemo.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.View; import java.util.Random; /** * Created by mChenys on 2015/12/1. */ public class CodeView extends View implements View.OnClickListener { private static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; //variables private String code; private Random random = new Random(); private int codeLength;//个数 private float fontSize;//字体大小 private Paint mTextPaint;//字体的画笔 private int paddingLeft;//左内边距 private int paddingTop;//上内边距 public void setCodeLength(int codeLength) { this.codeLength = codeLength; } public String getCode() { return code; } public CodeView(Context context) { this(context, null); } public CodeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { codeLength = 4; paddingLeft = dp2px(8); paddingTop = dp2px(5); mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setTextSize(25); mTextPaint.setColor(Color.BLACK); mTextPaint.setTypeface(Typeface.DEFAULT_BOLD); fontSize = mTextPaint.getTextSize();//字体大小 System.out.println("fontSize px:" + fontSize); mTextPaint.setTextAlign(Paint.Align.CENTER);//字体居中 code = createCode();//初始化的时候先生存code值,否则调用getCode()方法返回将是null //设置点击监听 setOnClickListener(this); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //左右边距+字体的字间距(这里字间距用fontSize代替) int width = (int) (2 * paddingLeft + (codeLength - 1) * fontSize); //上下边距+字体的高度 int height = (int) (2 * paddingTop + fontSize); setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.parseColor("#F2F2F2")); System.out.println("onDraw code is :" + code); char[] codeChar = code.toCharArray(); int fontX = 0; //每个字的X坐标 for (int i = 0; i < codeChar.length; i++) { fontX = (int) (paddingLeft + i * fontSize); String text = codeChar[i] + ""; canvas.drawText(text, fontX, paddingTop + fontSize, mTextPaint); } } private String createCode() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < codeLength; i++) { sb.append(CHARS[random.nextInt(CHARS.length)]); } return sb.toString(); } /** * dp转px * * @param dp * @return */ private int dp2px(float dp) { float density = getContext().getResources().getDisplayMetrics().density; return (int) (dp * density + 0.5f); } /** * sp to px */ public int sp2px(float sp) { float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity; return (int) (sp * fontScale + 0.5f); } //点击回调方法里面处理验证码的更新 @Override public void onClick(View v) { code = createCode();//重新生成新的验证码 invalidate(); //刷新界面UI,会调用onDraw方法 if (null != listener) { listener.OnChange(getCode());//通过自定义的监听接口返回新的验证码给调用者 } } //验证码变化的监听器 public interface OnCodeChangeListener { void OnChange(String code); } private OnCodeChangeListener listener; public void setOnCodeChangeListener(OnCodeChangeListener listener) { this.listener = listener; } }
/** * Created by mChenys on 2015/11/30. */ public class TextActivity extends Activity { private String inputCode; //用户输入的验证码值 private String verificationCode;//图片显示的验证码值 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text); } public void showCodeView(View view) { final Dialog dialog = new Dialog(TextActivity.this, R.style.myDialog); dialog.setContentView(R.layout.layout_code_dialog); //提示信息 final TextView tvInfo = (TextView) dialog.findViewById(R.id.tv_info); CodeView codeView = (CodeView) dialog.findViewById(R.id.code_view); final EditText edtInput = (EditText) dialog.findViewById(R.id.edt_code_input); //用户输入的验证码 inputCode = edtInput.getText().toString().trim(); //验证码图片显示的code verificationCode = codeView.getCode(); codeView.setOnCodeChangeListener(new CodeView.OnCodeChangeListener() { @Override public void OnChange(String code) { //点击验证码图片需要更新code值 verificationCode = code; } }); //确定按钮 dialog.findViewById(R.id.btn_sure).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { inputCode = edtInput.getText().toString().trim(); //校验验证码 if (TextUtils.isEmpty(inputCode)) { tvInfo.setText("请输入验证码!"); } else if (!verificationCode.equalsIgnoreCase(inputCode)) { tvInfo.setText("验证码错误"); } else { //校验成功 dialog.dismiss(); } } }); //取消按钮 dialog.findViewById(R.id.btn_cancle).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); dialog.setCanceledOnTouchOutside(false); dialog.show(); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#0f0" android:padding="20dp"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:onClick="showCodeView" /> </RelativeLayout>
1.未输入的情况下,点击确定,提示"请输入验证码!"
2.输入错误,提示"验证码错误"