一种基于自定义控件的验证码

来源:互联网 发布:淘宝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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新车迟迟不给合格证怎么办 手机系统剩余空间少怎么办 桌子被掉色的袋子印色怎么办 袋子掉色弄到柜子上怎么办 健身房老板跑路教练怎么办 健身房老板跑路了怎么办 淘宝断货了该怎么办 淘金猫网购频道账号换了怎么办 京东商城信用卡无法付款怎么办 京东第三方退货拒收怎么办 淘宝凑单收货地址不一样怎么办 淘宝凑单地址不一样怎么办 任性付还不了款怎么办 京东购物卷删了怎么办 荣耀手环3进水了怎么办 手机疏油层没了怎么办 快递到了处理中心不走了怎么办 京东取消了退款怎么办 我的订单删除了怎么办 近邻宝箱子误关怎么办 把收件人电话写错了怎么办 吧收件人电话写错了怎么办 速递易收件人电话写错怎么办 书包上的皮掉了怎么办 美亚很多商品不直邮中国怎么办 我想买刘涛用的化妆品贵妇膏怎么办 自提柜号码忘记了怎么办 京东商城误点确认收货怎么办 京东购物到货后怎么办 京东地址错了怎么办 没买运费险退货怎么办 没有买运费险退货怎么办 买的运费险换货怎么办 顾客买衣服说贵怎么办 卖衣服顾客说贵怎么办 汽车前保险杠刮蹭怎么办 洗手盆下水管堵了怎么办 装修好的卫生间漏水怎么办 马桶水箱盖碎了怎么办 马桶陶瓷盖碎了怎么办 电脑左右分屏了怎么办