您的位置:首页 > 移动开发 > Android开发

android自定义验证码倒计时View

2016-03-25 17:35 483 查看
关于自定义View的构造方法里面的参数的含义可以参考:

/article/5087383.html

代码:

倒计时类:

public class CountDownBtn extends Button implements View.OnClickListener
{
private static final String TAG = CountDownBtn.class.getSimpleName();
private String TIP;
private Integer TOTALTIME;
private int tempTotalTime;
private Integer normalBg;
private Integer countTimeBg;
private Activity activity;
private final static String SECOND = "秒";
private Timer timer;
private GetGenerateCodeListener listener;
private CountDownBtn instance;

public CountDownBtn(Context context)
{
this(context, null);
}

public CountDownBtn(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}

public CountDownBtn(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}

private void init(Context context, AttributeSet attrs, int defStyleAttr)
{
instance = this;
if(attrs != null)
{
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CountDown);
if(array.length() > 0)
{
TIP = array.getString(R.styleable.CountDown_defTip);
tempTotalTime = TOTALTIME = array.getInteger(R.styleable.CountDown_totalTime, 0);
normalBg = array.getResourceId(R.styleable.CountDown_normalBg, 0);
countTimeBg = array.getResourceId(R.styleable.CountDown_countTimeBg, 0);
LogUtils.i(TAG, "data " + TIP + "  " + tempTotalTime + "  " + normalBg + "  " + countTimeBg);
checkMessage(tempTotalTime, TIP, normalBg, countTimeBg);
array.recycle();
}
}
}

public void setActivity(Activity activity)
{
if (activity == null) {
throw new NullPointerException("activity non null ");
}
this.activity = activity;
}

private void start()
{
timer = new Timer();
timer.schedule(new TimerTask()
{
@Override
public void run()
{
activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
if (TOTALTIME > 0) {
CountDownBtn.this.instance.setText((TOTALTIME) + SECOND);
TOTALTIME = TOTALTIME - 1;
} else {
CountDownBtn.this.instance.setBackground(CountDownBtn.this.getResources().getDrawable(normalBg));
CountDownBtn.this.instance.setText(TIP);
timer.cancel();
TOTALTIME = tempTotalTime;
CountDownBtn.this.instance.setClickable(true);
}
}
});
}
}, 0, 1000);
}

/**
*该法是在layout中不设置相关属性,则需要在code里面动态的设置属性
* @param totalTime    倒计时的时间范围
* @param tipId        默认的提示语
* @param normalBgId   刚开始的默认背景.传入对应的Id
* @param countTimeBgId   倒计时时的背景颜色.传入对应的ID
*/
public void setMessage(int totalTime,int tipId,int normalBgId,int countTimeBgId)
{
tempTotalTime = this.TOTALTIME = totalTime;
this.TIP = this.getResources().getString(tipId);
normalBg = normalBgId;
countTimeBg = countTimeBgId;
checkMessage(TOTALTIME, TIP, normalBg, countTimeBg);
}

/**
* 校验数据合法性.(如果数据不合法,则使用默认值).
* @param totalTime
* @param tip
* @param normalBgId
* @param countTimeBgId
*/
private void checkMessage(int totalTime,String tip,int normalBgId,int countTimeBgId)
{
LogUtils.i(TAG,"checkMessage user count");
if(totalTime <= 0)
{
tempTotalTime = totalTime = 60;
}
if(totalTime > 120)
{
tempTotalTime = totalTime = 120;
}
if(TextUtils.isEmpty(tip))
{
TIP = this.getResources().getString(R.string.btn_generatecode);
}
if(normalBgId == 0)
{
normalBg = R.color.colorAccent;    //默认背景,可以自己定义
}
if(countTimeBgId == 0)
{
countTimeBg = R.color.colorPrimary;   //倒计时背景,可以自己定义
}
this.setBackground(getResources().getDrawable(normalBg));
this.setText(TIP);
this.setGravity(Gravity.CENTER);
this.setOnClickListener(this);
}

public void cance()
{
if(timer != null)
{
timer.cancel();
}
}

@Override
public void onClick(View v)
{
if(this.getText().equals(TIP))
{
this.setClickable(false);
this.setBackground(this.getResources().getDrawable(countTimeBg));
start();
if(listener != null)
{
listener.getGenerateCode();
}
}
}

/**
* 单击获取验证码以后的回调,在里面进行获取验证码的各种操作(networker)
*/
public interface GetGenerateCodeListener
{
void getGenerateCode();
}

public void setGenerateCodeListener(GetGenerateCodeListener listener)
{
this.listener = listener;
}
}


属性设置(attr):

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CountDown">
<!--默认提示语-->
<attr name="defTip" format="string"></attr>
<!--总计的倒计时时间以秒为单位-->
<attr name="totalTime" format="integer"></attr>
<!--正常情况下的背景-->
<attr name="normalBg" format="reference"></attr>
<!--倒计时的背景颜色-->
<attr name="countTimeBg" format="reference"></attr>
</declare-styleable>
</resources>


布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:orientation="vertical">

<android.support.v7.widget.Toolbar
android:id="@+id/toolBarBossLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

</android.support.v7.widget.Toolbar>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<android.support.design.widget.TextInputLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">

<AutoCompleteTextView
android:id="@+id/tvPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_phonenumber"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"/>

</android.support.design.widget.TextInputLayout>
<com.channelsoft.ggsj.view.CountDownBtn
android:id="@+id/btnGenerateCode"
android:layout_width="90.0dp"
android:layout_height="45.0dp"
android:layout_weight="0"
app:defTip = "@string/btn_generatecode"
app:totalTime = "60"
app:normalBg = "@android:color/holo_red_dark"
app:countTimeBg = "@android:color/white">

</com.channelsoft.ggsj.view.CountDownBtn>
</LinearLayout>

<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/tvPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"/>

</android.support.design.widget.TextInputLayout>

<Button
android:id="@+id/bntLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn_login"
/>
</LinearLayout>
</layout>


Activity:activity使用了Data Binding的技术,关于这个可以参考文档 :

https://segmentfault.com/a/1190000002876984

public class BossLoginActivity extends BaseActivity implements View.OnClickListener,CountDownBtn.GetGenerateCodeListener
{
private ActivityBossLoginBinding binding ;
private GenerateCodeViewModel generateCodeViewModel;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_boss_login);
binding.bntLogin.setOnClickListener(this);
binding.btnGenerateCode.setActivity(this);
binding.btnGenerateCode.setGenerateCodeListener(this);
}

@Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.bntLogin:
if(checkPhoneNumber())
{
generateCodeViewModel = new GenerateCodeViewModel();
generateCodeViewModel.getGenerateCode(binding.tvPhone.getText().toString().trim());
}
break;
case R.id.btnGenerateCode:

break;
}
}

@Override
public void getGenerateCode()
{

}

@Override
protected void onDestroy()
{
super.onDestroy();
binding.btnGenerateCode.cance();
}

private boolean checkPhoneNumber()
{
return true;
}
}


代码比较简单,这里不多做介绍,有什么问题,欢迎批评,android小白一枚.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: