一种基于自定义控件的验证码
来源:互联网 发布:淘宝ysl口红真假 编辑:程序博客网 时间:2024/05/20 21:48
主要是利用自定义View,随机划线画点,不再赘述,上码
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="400dp" android:id="@+id/custom"> <com.mrpeng.customviewdemo.CustomTitleView android:id="@+id/customview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:padding="10dp" custom:titleText_customview="3712" custom:titleTextSize_custome="30sp" custom:titleTextColor_customview="#ff0000"/> </RelativeLayout><LinearLayout android:layout_alignBottom="@id/custom" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:orientation="horizontal"> <Button android:layout_weight="1" android:id="@+id/btn_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="看不清,换"/> <EditText android:id="@+id/et_num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginLeft="20dp" android:hint="请输入数字"/> <Button android:id="@+id/btn_commit" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="提交"/></LinearLayout></RelativeLayout>
mainActivity展示
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button mBtn_change; private CustomTitleView mCustomview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn_change = (Button)findViewById(R.id.btn_change); mBtn_change.setOnClickListener(this); Button btn_commit = (Button)findViewById(R.id.btn_commit); btn_commit.setOnClickListener(this); mCustomview = (CustomTitleView)findViewById(R.id.customview); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.btn_change: changeCustomView(); break; case R.id.btn_commit: break; } } private void changeCustomView() { String randomText = mCustomview.randomText(); mCustomview.setTitle(randomText); mCustomview.invalidate(); }}
重点是这里的自定义View
public class CustomTitleView extends View implements ChangeView{ public void setTitle(String title) { mTitle = title; } private String mTitle; private int mTitleTextColor; private int mTitleTestSize; private Paint mPaint; private Rect mBound; /** * 第一个构造 java代码创建视图的时候被调用,如果是从xml填充的视图,就不会调用这个 * 第二个构造 在xml创建时调用 * 第三个构造,不知道 * @param context */ public CustomTitleView(Context context) { super(context); } public CustomTitleView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleView);// TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, null, 0); int n = typedArray.getIndexCount(); for(int i=0;i<n;i++){ int attr = typedArray.getIndex(i); switch(attr){ case R.styleable.CustomTitleView_titleText_customview: mTitle = typedArray.getString(attr); break; case R.styleable.CustomTitleView_titleTextColor_customview: mTitleTextColor = typedArray.getColor(attr, Color.BLACK); break; case R.styleable.CustomTitleView_titleTextSize_custome: // 默认设置为16sp,TypeValue也可以把sp转化为px mTitleTestSize = typedArray.getDimensionPixelSize(attr, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics() )); break; } } typedArray.recycle(); mPaint = new Paint(); mPaint.setTextSize(mTitleTestSize); mBound = new Rect(); mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBound); this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mTitle = randomText(); postInvalidate(); } }); } public String randomText() { StringBuffer sb = new StringBuffer(); for(int j=0;j<4;j++){ Random random1 = new Random(); int h = random1.nextInt(10); sb.append(""+h); } return sb.toString(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * EXACTLY:一般是设置了明确的值或者是MATCH_PARENT * AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT * UNSPECIFIED:表示子布局想要多大就多大,很少使用 */ int wideMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if(wideMode==MeasureSpec.EXACTLY){//已经设置明确值,或者match_parent width=widthSize; }else { mPaint.setTextSize(mTitleTestSize); mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBound); float textWidth = mBound.width(); int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight()); width = desired; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { mPaint.setTextSize(mTitleTestSize); mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBound); float textHeight = mBound.height(); int desired = (int) (getPaddingTop()+ textHeight + getPaddingBottom() ); height = desired; } /** * 重要方法,onMeasure调用 */ setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { mPaint.setColor(Color.YELLOW); canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); mPaint.setColor(mTitleTextColor);// canvas.drawText(mTitle,getWidth()/2-mBound.width()/2,getHeight()/2+mBound.height()/2,mPaint); int start=getWidth()/2-mBound.width()/2; /** * 数字随机摆放 */ for(int i=0;i<4;i++){ canvas.drawText(mTitle.substring(i,i+1),start,CheckUtil.getTextPosition(getMeasuredHeight()),mPaint); start+=mBound.width()/5; } /** * 画随机位置的线 */ mPaint.setStrokeWidth(3); for(int i=0;i<8;i++){ int[] line = CheckUtil.getLine(getMeasuredWidth(), getMeasuredHeight()); canvas.drawLine(line[0],line[1], line[2], line[3],mPaint);// float top = (float)(Math.random()*getMeasuredHeight());// float bottom = top+1;// float left = (float)(0.1*getMeasuredWidth());// float right = (float)(0.9*getMeasuredWidth());// canvas.drawRect(left,top,right,bottom,mPaint); } /** * 画点 */ for(int i=0;i<80;i++){ canvas.drawCircle(CheckUtil.getPosition(getMeasuredWidth()),CheckUtil.getPosition(getMeasuredHeight()),1,mPaint); } } @Override public void updateView() { mTitle = randomText(); postInvalidate(); }}
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="titleText_customview" format="string"/> <attr name="titleTextColor_customview" format="color"/> <attr name="titleTextSize_custome" format="dimension"/> <declare-styleable name="CustomTitleView"> <attr name="titleText_customview"/> <attr name="titleTextColor_customview"/> <attr name="titleTextSize_custome"/> </declare-styleable></resources>用于产生随机点和线的工具类
public class CheckUtil
{
public static int[] getLine(int width, int height){
int [] lineCoordinate=new int[4];
for(int i=0;i<4;i+=2){
lineCoordinate[i]= (int)(Math.random()*width);
lineCoordinate[i+1]= (int)(Math.random()*height);
}
return lineCoordinate;
}
public static int getTextPosition(int height){ int tempPosition = (int)( Math.random()*height ); if(tempPosition<0.5*height ){ tempPosition+=0.5*height; } return tempPosition ;}public static int getPosition(int height){ int tempPosition = (int)( Math.random()*height ); if(tempPosition<1){ tempPosition+=1; } return tempPosition;}
}
源码
0 0
- 一种基于自定义控件的验证码
- 自定义“验证码”控件
- 自定义“验证码”控件
- 自定义“验证码”控件
- 自定义验证码控件
- 一种基于memcache或redis缓存架构的验证码
- 制作验证码的另外一种方法(不用控件)
- 一种带动画自定义控件的封装
- 一种正确调用自定义控件的方法
- 【自定义控件】练习:验证码
- 自定义控件实现验证码
- 自定义view之一:自定义验证码控件
- Android自定义View 做个简单的验证码控件
- 基于cookie验证的php应用的一种SSO解决方案
- 自定义短信验证码中的倒计时控件
- Android自定义View--验证码控件
- 自定义控件之_验证码
- 自定义验证码发送倒计时控件
- AFHTTPRequestOperationManager在引入afnetworking后依然找不到
- DelayQueue 学习和应用
- Android Studio "佛祖保佑 永无bug" 注释模板设置详解(仅供娱乐)
- gcc/g++
- table前端分页
- 一种基于自定义控件的验证码
- python正则表达式简单使用
- HBase-----数据模型。定位一条数据4个标签(TableName, RowKey, ColumnKey, Timestamp)
- 夹杂数字字母大小写的字符串排序方法
- JavaScript substr() 方法实例
- Leetcode-single-number
- 2016春季练习——水
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- spring,mybatis事务管理配置与@Transactional注解使用