自定义发送验证码按钮(没有实现发送验证码业务 只有UI效果)

来源:互联网 发布:java调用wsdl 编辑:程序博客网 时间:2024/06/09 23:40

自定义发送验证码按钮(没有实现发送验证码业务 只有UI效果)

大家都知道在一个项目的开发中,发送短信验证码是必不可少的业务,接下来给大家讲的就是如何自定义发送短信验证码的按钮。

第一步:新建一个java类:GetCode.java

package com.wj.imchatclient.commonmodle.view;import android.content.Context;import android.content.res.TypedArray;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.EditText;import android.widget.TextView;import com.wj.imchatclient.R;import com.wj.imchatclient.commonmodle.utils.L;import com.wj.imchatclient.commonmodle.utils.T;import com.wj.imchatclient.commonmodle.utils.ValueUtils;/** * 发送验证码的按钮 * Created by WJ on 2016/7/31. */public class GetCode extends TextView {    private final String TAG = "GetCode";//标签    private final int UPDATE_TEXT = 1;//更新文本内容的what    private final int UPDATE_STATUS = 2;//更新状态    private boolean canClick = false;//是否可以点击    private int delay_time = 10;//一次倒计时的总数s    private int time = delay_time;//正在倒计时的s    private OnGetCodeListener onGetCodeListener;    public void setOnGetCodeListener(OnGetCodeListener onGetCodeListener) {        this.onGetCodeListener = onGetCodeListener;    }    public interface OnGetCodeListener {        EditText getInput();        boolean getPhone();        void getCode();    }    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == UPDATE_TEXT) {                //更新内容                setText(ValueUtils.getString(R.string.get_code) + "(" + time + ")");            } else if (msg.what == UPDATE_STATUS) {                //更新状态                setEnabled(canClick);                setText(ValueUtils.getString(R.string.get_code));            }        }    };    public GetCode(Context context) {        super(context);    }    public GetCode(Context context, AttributeSet attrs) {        super(context, attrs);        initData(context, attrs);    }    public GetCode(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initData(context, attrs);    }    public GetCode(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initData(context, attrs);    }    public void initData(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GetCode);        delay_time = typedArray.getInteger(R.styleable.GetCode_delay_time, delay_time);        time = delay_time;        L.e(TAG, "正在加载属性=" + delay_time);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        L.e(TAG, "onTouchEvent==" + event.getAction());        if (event.getAction() == MotionEvent.ACTION_UP) {            //按下去了            if (onGetCodeListener != null) {                boolean isPhone = onGetCodeListener.getPhone();//发送验证码                L.e(TAG, "是不是手机号呢?" + isPhone);                if (isPhone) {                    //是手机号                    canClick = true;                } else {                    canClick = false;                    //设置input的焦点                    onGetCodeListener.getInput().setFocusable(true);                    onGetCodeListener.getInput().setFocusableInTouchMode(true);                    onGetCodeListener.getInput().requestFocus();                    onGetCodeListener.getInput().requestFocusFromTouch();                }            }            if (canClick) {                canClick = false;                setEnabled(canClick);                startTimeThread();//启动倒计时                if (onGetCodeListener != null) {                    onGetCodeListener.getCode();                }            } else {                T.show(getContext(), "请输入正确的手机号");            }            L.e(TAG, "canClick==" + canClick);        }        return super.onTouchEvent(event);    }    @Override    protected void onWindowVisibilityChanged(int visibility) {        super.onWindowVisibilityChanged(visibility);        L.e(TAG, "onWindowVisibilityChanged==" + visibility + "===" + (visibility == GONE));        if (visibility == GONE) {            //内容没了 停止线程减少不必要的资源            canClick = true;            setEnabled(canClick);        }    }    /**     * 倒计时线程     */    private void startTimeThread() {        new Thread(new Runnable() {            @Override            public void run() {                while (canClick == false) {                    time--;                    L.e(TAG, Thread.currentThread().getName() + "线程还在运行中======" + time);                    if (time == 0) {                        time = delay_time;                        canClick = true;                        handler.sendEmptyMessage(UPDATE_STATUS);                    } else {                        handler.sendEmptyMessage(UPDATE_TEXT);                    }                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }}

第二步:注意在以上的自定义View中使用了自定义的属性,所以需要在res/values/atts.xml中添加以下内容:

<declare-styleable name="GetCode">        <attr name="delay_time" format="integer"/></declare-styleable>

添加这个的作用是可以在布局中自定义倒计时的时间(单位:s)

第三步:在布局xml中使用GetCode自定义View(注意:笔者在这没有使用Button,而是使用了TextView 所以需要设置宽高来改变TextView的外观 具体为什么不用Button就是笔者习惯使用TextView了。)

<com.wj.imchatclient.commonmodle.view.GetCode            android:id="@+id/v_getcode"            android:layout_width="@dimen/dp100"            android:layout_height="@dimen/dp30"            android:layout_gravity="center_vertical"            android:layout_marginLeft="@dimen/dp5"            android:layout_marginRight="@dimen/dp5"            android:background="@drawable/bg_get_code"            android:clickable="true"            android:gravity="center"            android:text="@string/get_code"            android:textColor="@android:color/white"            app:delay_time="60"             />

以上属性笔者只讲一下

app:delay_time="60"android:background="@drawable/bg_get_code"

app:delay_time:就是刚刚说的自定义属性了 60表示倒计时长为60s

android:background:这里引用了drawable对象选择器,需要在res/drawable下新建一个xml命名为:bg_get_code

1新建 .bg_get_code.xml 代码如下: 选择器

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_enabled="false" android:drawable="@drawable/bg_get_code_false"/>    <item android:state_enabled="true" android:drawable="@drawable/bg_get_code_true"/></selector>

2.新建 bg_get_code_true.xml:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <corners android:radius="@dimen/dp5"/>    <solid android:color="@color/colorAccent"/></shape>

3.新建 bg_get_code_false.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <corners android:radius="@dimen/dp5" />    <solid android:color="@color/c_9B9DB1" /></shape>

第四步:在Activity中获取GetCode实例 设置监听

  GetCode getCode= (GetCode) findViewById(R.id.v_getcode);  getCode.setOnGetCodeListener(this);
    @Override    public EditText getInput() {        return etMobile;    }    @Override    public boolean getPhone() {        return RegularUtils.phone(etMobile.getText().toString());    }    @Override    public void getCode() {        //发送验证码        T.show(this, "正在发送验证码到-" + etMobile.getText().toString());    }

getInput:返回输入框的实例EditText。

getPhone:作用是返回一个是不是手机号的boolean值,true是手机号 会调用getCode方法去实现发送验证码业务,false不是手机号 不会调用getCode方法。

getCode:实现发送验证码业务。

0 0
原创粉丝点击