一、需求
二、代码实现
资源文件
drawable/editext_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/shape_edit_focus"/>
<item android:drawable="@drawable/shape_edit_normal"/>
</selector>
values/strings.xml
<resources>
<string name="app_name">middlewidget</string>
<string name="title_activity_drawable_state">DrawableStateActivity</string>
<string name="prompt_email">Email</string>
<string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string>
<string name="action_sign_in_short">Sign in</string>
<string name="welcome">"Welcome !"</string>
<string name="invalid_username">Not a valid username</string>
<string name="invalid_password">Password must be >5 characters</string>
<string name="login_failed">"Login failed"</string>
<!--自定义-->
<string name="login_by_password">密码登录</string>
<string name="login_by_verifycode">验证码登录</string>
<string name="phone_number">手机号码:</string>
<string name="input_phone_number">请输入手机号码</string>
<string name="login_password">登录密码:</string>
<string name="input_password">请输入密码</string>
<string name="forget_password">忘记密码</string>
<string name="remember_password">记住密码</string>
<string name="login">登      录</string>
<string name="input_new_password">输入新密码:</string>
<string name="input_new_password_hint">请输入新密码</string>
<string name="confirm_new_password">确认新密码:</string>
<string name="input_new_password_again">请再次输入新密码</string>
<string name="verifycode">    验证码:</string>
<string name="verifycode2">        验证码:</string>
<string name="input_verifycode">请输入验证码</string>
<string name="get_verfycode">获取验证码</string>
<string name="done">确      定</string>
</resources>
values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<!-- 自定义-->
<color name="grey">#cccccc</color>
</resources>
values/dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="common_font_size">17sp</dimen>
<dimen name="button_font_size">20sp</dimen>
<dimen name="item_layout_height">50sp</dimen>
</resources>
布局文件:
layout/activity_login_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RadioGroup
android:id="@+id/rg_login"
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_password"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:checked="true"
android:text="@string/login_by_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<RadioButton
android:id="@+id/rb_verifycode"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/login_by_verifycode"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/phone_number"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<EditText
android:id="@+id/et_phone"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/editext_selector"
android:hint="@string/input_phone_number"
android:inputType="number"
android:maxLength="11"
android:textColor="@color/black"
android:textColorHint="@color/grey"
android:textSize="@dimen/common_font_size"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/login_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/editext_selector"
android:hint="@string/input_password"
android:inputType="numberPassword"
android:maxLength="6"
android:textColor="@color/black"
android:textColorHint="@color/grey"
android:textSize="@dimen/common_font_size" />
<Button
android:id="@+id/btn_forget"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:text="@string/forget_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
</RelativeLayout>
</LinearLayout>
<CheckBox
android:id="@+id/ck_remember"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/remember_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size"
android:button="@drawable/checkbox_selector"
/>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/login"
android:textColor="@color/black"
android:textSize="@dimen/button_font_size"
/>
此布局文件对应的activity com/example/middlewidget/LoginForgetActivty.java
public class LoginForgetActivty extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener {
private String mPhone;
private String mRandomVerifyCode;
private EditText et_verifycode;
private EditText et_password_first;
private EditText et_password_second;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_forget_activty);
// 从上一个页面获取要修改密码的手机号码
Intent intent = getIntent();
mPhone = intent.getStringExtra("phone");
et_password_first = findViewById(R.id.et_password_first);
et_password_second = findViewById(R.id.et_password_second);
et_verifycode = findViewById(R.id.et_verifycode);
// 文本内容监听
et_password_first.addTextChangedListener(new PasswordWatcher(et_password_first, 6));
et_password_second.addTextChangedListener(new PasswordWatcher(et_password_second, 6));
et_password_first.setOnFocusChangeListener(this);
et_password_second.setOnFocusChangeListener(this);
findViewById(R.id.btn_verifycode).setOnClickListener(this);
findViewById(R.id.btn_confirm).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
// 点击了获取验证码按钮
case R.id.btn_verifycode:
mRandomVerifyCode = String.format("%06d", new Random().nextInt(999999));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.verifycode));
builder.setMessage("你的是手机号" + mPhone + "本次的验证码是" + mRandomVerifyCode + ",请记住验证码");
builder.setPositiveButton("我记住了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 点击后自动将验证码填入验证码框
et_verifycode.setText(mRandomVerifyCode);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
break;
// 点击了确定按钮
case R.id.btn_confirm:
String first_password = et_password_first.getText().toString();
String second_password = et_password_second.getText().toString();
if (first_password.length() < 6) {
Toast.makeText(this, "请输入6位密码", Toast.LENGTH_SHORT).show();
}
if (!first_password.equals(second_password)) {
Toast.makeText(this, "两次输入密码不相等,请重新输入", Toast.LENGTH_SHORT).show();
return;
}
String verifyCode = et_verifycode.getText().toString();
if (!verifyCode.equals(mRandomVerifyCode)) {
Toast.makeText(this, "请输入正确的验证码", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "密码修改成功", Toast.LENGTH_SHORT).show();
// 以下把修改好的新密码返回给上一个密码
Intent intent = new Intent();
intent.putExtra("new_password", first_password);
setResult(Activity.RESULT_OK, intent);
finish();
break;
}
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
String first_password = et_password_first.getText().toString();
if (TextUtils.isEmpty(first_password) || first_password.length() < 6) {
et_password_first.requestFocus();
Toast.makeText(this, "请输入6位密码", Toast.LENGTH_SHORT).show();
}
}
}
private class PasswordWatcher implements TextWatcher {
private EditText editText;
private int mMaxLength;
public PasswordWatcher(EditText editText, int maxLength) {
this.editText = editText;
this.mMaxLength = maxLength;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String str = s.toString();
if (str.length() == mMaxLength) {
ViewUtil.hideOneInputMethod(LoginForgetActivty.this, editText);
}
}
}
}
第二个布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".LoginMainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/input_new_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<EditText
android:id="@+id/et_password_first"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/editext_selector"
android:hint="@string/input_new_password"
android:inputType="numberPassword"
android:maxLength="6"
android:textColor="@color/black"
android:textColorHint="@color/grey"
android:textSize="@dimen/common_font_size"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/confirm_new_password"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<EditText
android:id="@+id/et_password_second"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/editext_selector"
android:hint="@string/input_new_password_again"
android:inputType="numberPassword"
android:maxLength="6"
android:textColor="@color/black"
android:textColorHint="@color/grey"
android:textSize="@dimen/common_font_size" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_layout_height"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/verifycode2"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<EditText
android:id="@+id/et_verifycode"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/editext_selector"
android:hint="@string/input_verifycode"
android:inputType="number"
android:maxLength="6"
android:textColor="@color/black"
android:textColorHint="@color/grey"
android:textSize="@dimen/common_font_size" />
<Button
android:id="@+id/btn_verifycode"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:text="@string/get_verfycode"
android:textColor="@color/black"
android:textSize="@dimen/common_font_size" />
</RelativeLayout>
</LinearLayout>
<Button
android:id="@+id/btn_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/done"
android:textColor="@color/black"
android:textSize="@dimen/button_font_size"
/>
</LinearLayout>
此布局对应的activity
public class LoginForgetActivty extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener {
private String mPhone;
private String mRandomVerifyCode;
private EditText et_verifycode;
private EditText et_password_first;
private EditText et_password_second;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_forget_activty);
// 从上一个页面获取要修改密码的手机号码
Intent intent = getIntent();
mPhone = intent.getStringExtra("phone");
et_password_first = findViewById(R.id.et_password_first);
et_password_second = findViewById(R.id.et_password_second);
et_verifycode = findViewById(R.id.et_verifycode);
// 文本内容监听
et_password_first.addTextChangedListener(new PasswordWatcher(et_password_first, 6));
et_password_second.addTextChangedListener(new PasswordWatcher(et_password_second, 6));
et_password_first.setOnFocusChangeListener(this);
et_password_second.setOnFocusChangeListener(this);
findViewById(R.id.btn_verifycode).setOnClickListener(this);
findViewById(R.id.btn_confirm).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
// 点击了获取验证码按钮
case R.id.btn_verifycode:
mRandomVerifyCode = String.format("%06d", new Random().nextInt(999999));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.verifycode));
builder.setMessage("你的是手机号" + mPhone + "本次的验证码是" + mRandomVerifyCode + ",请记住验证码");
builder.setPositiveButton("我记住了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 点击后自动将验证码填入验证码框
et_verifycode.setText(mRandomVerifyCode);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
break;
// 点击了确定按钮
case R.id.btn_confirm:
String first_password = et_password_first.getText().toString();
String second_password = et_password_second.getText().toString();
if (first_password.length() < 6) {
Toast.makeText(this, "请输入6位密码", Toast.LENGTH_SHORT).show();
}
if (!first_password.equals(second_password)) {
Toast.makeText(this, "两次输入密码不相等,请重新输入", Toast.LENGTH_SHORT).show();
return;
}
String verifyCode = et_verifycode.getText().toString();
if (!verifyCode.equals(mRandomVerifyCode)) {
Toast.makeText(this, "请输入正确的验证码", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "密码修改成功", Toast.LENGTH_SHORT).show();
// 以下把修改好的新密码返回给上一个密码
Intent intent = new Intent();
intent.putExtra("new_password", first_password);
setResult(Activity.RESULT_OK, intent);
finish();
break;
}
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
String first_password = et_password_first.getText().toString();
if (TextUtils.isEmpty(first_password) || first_password.length() < 6) {
et_password_first.requestFocus();
Toast.makeText(this, "请输入6位密码", Toast.LENGTH_SHORT).show();
}
}
}
private class PasswordWatcher implements TextWatcher {
private EditText editText;
private int mMaxLength;
public PasswordWatcher(EditText editText, int maxLength) {
this.editText = editText;
this.mMaxLength = maxLength;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String str = s.toString();
if (str.length() == mMaxLength) {
ViewUtil.hideOneInputMethod(LoginForgetActivty.this, editText);
}
}
}
}