当前位置: 首页 > news >正文

Android学习之登录界面(包含忘记密码 记住密码)(java + 详细注释 + 源码)

整体的界面:

页面的布局:

功能介绍:

1:对账号密码的校验。

账号不为11位,密码不正确的时候提示对应的信息。

// 先去判断手机号码是否符合if(phone.length() < 11) {Toast.makeText(this,"请输入正确的手机号码", Toast.LENGTH_SHORT).show();return;}

2:点击验证码登录时,显示不同的界面。

通过对RadioGroup设置监听

 // 给 rg_login设置单选监听rb_login.setOnCheckedChangeListener(this);

通过获取 checkedId 就可以知道是 密码登录还是验证码登录,然后设置对应的文本内容就可以。

 

 @Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {// 选择的是 密码登录的方式if(checkedId == R.id.rb_password) {tv_password.setText(getString(R.string.login_password));et_password.setHint(getString(R.string.input_password));btn_forget.setText(getString(R.string.forget_password));ck_remember.setVisibility(View.VISIBLE); // 验证码登录的时候 要把记住密码这个给pass掉String password = preferences.getString("password", "null");if(!password.equals("null")) {et_password.setText(password);}} else if(checkedId == R.id.rb_verifycode) { // 选择的是 验证码的登录方式tv_password.setText(getString(R.string.verifycode));et_password.setHint(getString(R.string.input_verifycode));et_password.setText("");btn_forget.setText(getString(R.string.get_verifycode));ck_remember.setVisibility(View.GONE); // 验证码登录的时候 要把记住密码这个给pass掉}}

3:忘记密码

 

点击忘记密码之后,首先校验的是你输入手机号没?要是没有手机号的话要做出提示。

用的是intent 指定要跳转的界面.class,可以在跳转的时候去携带指定的信息。

intent.putExtra(key, value);

 // 那么这里执行的是 此时要跳到找回密码页面// 要去携带手机号码进行跳转Intent intent = new Intent(this, LoginForgetActivity.class);intent.putExtra("phone", phone);register.launch(intent);

对两次新密码一致性进行校验

 

4:生产随机的6位验证码

 

 // 生成6位的随机验证码verifyCode = String.format("%06d", new Random().nextInt(999999));// 弹出对话框 提示用户AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("密码可以忘,但验证码不能忘");builder.setMessage("本次验证码是" + verifyCode + ",请输入验证码");builder.setPositiveButton("好的", null);AlertDialog dialog = builder.create();dialog.show();

找回密码后把数据带回到登录界面

 

finish() 表示这个界面的任务完成了,就可以回到之前调用我的那个界面了。

 // 进行确认的操作// 要去跳转到登录界面 然后填充具体的数据// 进行相关操作后,设置返回结果Intent resultIntent = new Intent();Bundle bundle = new Bundle();// 获取传入的 phone 数据String phone = getIntent().getStringExtra("phone");// 随便带回一个密码都可以bundle.putString("password", et_password_first.getText().toString());bundle.putString("phone", phone);resultIntent.putExtras(bundle); // "返回的数据" 替换为实际要返回的值setResult(RESULT_OK, resultIntent);finish(); // 关闭 LoginForgetActivity 页面

5:记住密码

输入正确的账号和密码,并点击记住密码之后,下一次再次登录的时候 就会把xml里面的文件给写到文本框里面。

 

 preferences = getSharedPreferences("config", Context.MODE_PRIVATE);

上面代码里面参数的介绍:

config: 表示的进行存储和读取的文件名称(后缀默认是 .xml),

Context.MODE_PRIVATE: 表示的是 私有的数据,不允许别人进行访问。

该文件的位置:/data/data/应用包名/shared_prefs/文件名.xml

通过Map(key, value)的形式进行存储的。 

 

全部代码:

 activity_login_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RadioGroupandroid:id="@+id/rg_login"android:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--checked = true 表示的默认密码登录--><RadioButtonandroid:id="@+id/rb_password"android:layout_width="0dp"android:layout_weight="1"android:checked="true"android:layout_height="match_parent"android:text="@string/login_by_password"android:textSize="@dimen/common_font_size"android:textColor="@color/black"/><RadioButtonandroid:id="@+id/rb_verifycode"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"android:text="@string/login_by_verifycode"android:textSize="@dimen/common_font_size"android:textColor="@color/black"/></RadioGroup><!--这个显示的是具体的登录操作--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--设置这个文本是水平和垂直上是居中的gravity="center"--><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:text="@string/phone_number"android:gravity="center"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><!--这里的background 引用的是以前写的 @drawable 里面提前写好的对输入的类型(数字) 以及长度进行限制提示的文字的颜色设置为 灰色的 md这个也是自己去写的--><EditTextandroid:id="@+id/et_phone"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"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><!--这个显示的是让用户去输入密码--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--设置这个文本是水平和垂直上是居中的gravity="center"--><TextViewandroid:id="@+id/tv_password"android:layout_width="wrap_content"android:layout_height="match_parent"android:text="@string/login_password"android:gravity="center"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><!--这里用的是 相对布局 方便进行直接定位 忘记密码是要悬浮在最右边的--><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><EditTextandroid: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="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="@dimen/common_font_size"/><!--这里的 alignParentEnd 相对的是 父的位置 在父盒子的最右边这里推荐的是 End 这个新更改的--><Buttonandroid:id="@+id/btn_forget"android:layout_alignParentEnd="true"android:layout_width="wrap_content"android:layout_height="match_parent"android:textColor="@color/black"android:textSize="@dimen/common_font_size"android:text="@string/forget_password"/></RelativeLayout></LinearLayout><CheckBoxandroid:id="@+id/ck_remember"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/remember_password"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><Buttonandroid: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"/></LinearLayout>

LoginMainActivity.java 

package com.findyou.myapplication;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;import com.findyou.myapplication.util.ViewUtil;import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;/*** 模拟登录注册时候* 1:账号密码登录* 2:验证码登录*/
public class LoginMainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, View.OnClickListener {private TextView tv_password;private EditText et_password;private Button btn_forget;private CheckBox ck_remember;private EditText et_phone;private RadioButton rb_password;private RadioButton rb_verifycode;private ActivityResultLauncher<Intent> register;private Button btn_login;// TODO: 这里的密码校验是写死的 后期要进行修改private String mPassword = "666666";private String verifyCode;private SharedPreferences preferences;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login_main);// 先去获取 按钮组的idRadioGroup rb_login = findViewById(R.id.rg_login);tv_password = findViewById(R.id.tv_password);et_password = findViewById(R.id.et_password);et_phone = findViewById(R.id.et_phone);// 按钮btn_forget = findViewById(R.id.btn_forget);ck_remember = findViewById(R.id.ck_remember);rb_password = findViewById(R.id.rb_password);rb_verifycode = findViewById(R.id.rb_verifycode);btn_login = findViewById(R.id.btn_login);// 给 rg_login设置单选监听rb_login.setOnCheckedChangeListener(this);et_phone.addTextChangedListener(new HideTextWatcher(et_phone, 11));et_password.addTextChangedListener(new HideTextWatcher(et_password, 6));btn_forget.setOnClickListener(this);register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult result) {// 回来的时候就来到了这里if (result.getResultCode() == Activity.RESULT_OK) {Intent data = result.getData();if (data != null) {// 把带回来的账号和密码进行填充Bundle extras = data.getExtras();if (extras != null) {et_phone.setText(extras.getString("phone"));}if (extras != null) {et_password.setText(extras.getString("password"));}// 填充之后 要把带回来的密码设置为之前写死的那个if (extras != null) {mPassword = extras.getString("password");}Toast.makeText(LoginMainActivity.this, "找回密码成功, 快登录吧", Toast.LENGTH_SHORT).show();}}}});btn_login.setOnClickListener(this);// 一定要先进行初始化// 初始化preferencespreferences = getSharedPreferences("config", Context.MODE_PRIVATE);String remember = preferences.getString("rememberPassword", "null");if(!remember.equals("null") && !remember.equals("false")) {// 要先看看有没有登录成功的时候 点击记住密码这个选项reload();}}/*** 获取自己的偏好*/private void reload() {String phone = preferences.getString("phone", "null");if(!phone.equals("null")) {et_phone.setText(phone);}String password = preferences.getString("password", "null");if(!password.equals("null")) {et_password.setText(password);}String remember = preferences.getString("rememberPassword", "null");if(!remember.equals("null")) {ck_remember.setChecked(Boolean.valueOf(remember));}}@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {// 选择的是 密码登录的方式if(checkedId == R.id.rb_password) {tv_password.setText(getString(R.string.login_password));et_password.setHint(getString(R.string.input_password));btn_forget.setText(getString(R.string.forget_password));ck_remember.setVisibility(View.VISIBLE); // 验证码登录的时候 要把记住密码这个给pass掉String password = preferences.getString("password", "null");if(!password.equals("null")) {et_password.setText(password);}} else if(checkedId == R.id.rb_verifycode) { // 选择的是 验证码的登录方式tv_password.setText(getString(R.string.verifycode));et_password.setHint(getString(R.string.input_verifycode));et_password.setText("");btn_forget.setText(getString(R.string.get_verifycode));ck_remember.setVisibility(View.GONE); // 验证码登录的时候 要把记住密码这个给pass掉}}@Overridepublic void onClick(View v) {String phone = et_phone.getText().toString();if(v.getId() == R.id.btn_forget) {// 用户点击了 忘记密码这个操作// 先去判断手机号码是否符合if(phone.length() < 11) {Toast.makeText(this,"请输入正确的手机号码", Toast.LENGTH_SHORT).show();return;}// 选择的是密码登录if(rb_password.isChecked()) {// 那么这里执行的是 此时要跳到找回密码页面// 要去携带手机号码进行跳转Intent intent = new Intent(this, LoginForgetActivity.class);intent.putExtra("phone", phone);register.launch(intent);} else if(rb_verifycode.isChecked()) { // 此时选择的是 验证码登录的操作// 生成6位的随机验证码verifyCode = String.format("%06d", new Random().nextInt(999999));// 弹出对话框 提示用户AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("请记住验证码");builder.setMessage("手机号" + phone + ", 本次验证码是" + verifyCode + ",请输入验证码");builder.setPositiveButton("好的", null);AlertDialog dialog = builder.create();dialog.show();}} else if(v.getId() == R.id.btn_login) { // 选择的是登录操作if(phone.length() < 11) {Toast.makeText(this,"请输入正确的手机号码", Toast.LENGTH_SHORT).show();return;}// 选择的是 密码的登录方式if(rb_password.isChecked()) {if(!mPassword.equals(et_password.getText().toString())) {Toast.makeText(this, "密码不正确", Toast.LENGTH_SHORT).show();return;}//提示用户登录成功loginSuccess();} else if(rb_verifycode.isChecked()) { // 验证码方式的校验if(verifyCode == null) {// 还没获取验证码呢 老弟Toast.makeText(this, "老弟,没获取验证码哦。别说你是为了测试bug", Toast.LENGTH_SHORT).show();return;} else {if(!verifyCode.equals(et_password.getText().toString())) {Toast.makeText(this, "验证码不正确", Toast.LENGTH_SHORT).show();return;} else {loginSuccess();}}}}}/*** 提示用户登录成功*/private void loginSuccess() {String desc = String.format("您的手机号是%s, 恭喜你通过了登录验证,点击 ``确认`` 按钮返回上个页面", et_phone.getText().toString());// 弹出对话框 提醒用户登录成功AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("登录成功");builder.setMessage(desc);builder.setPositiveButton("确定返回", ((dialog, which) -> {// 结束当前的页面finish();}));builder.setNegativeButton("我再看看", null);AlertDialog dialog = builder.create();dialog.show();// 登录成功要保存用户的数据到文件里面Map<String, String>mp = messageToMap();keepMessage(mp);}/*** 把信息转换为 Map* @return 转换后的Map集合*/private Map<String, String> messageToMap() {Map<String, String>mp = new HashMap<>();mp.put("phone", et_phone.getText().toString());mp.put("password", et_password.getText().toString());mp.put("rememberPassword", String.valueOf(ck_remember.isChecked()));return mp;}/*** 把传来的Map信息 存储到文件里面* @param mp 存储信息的Map集合*/private void keepMessage(Map<String, String> mp) {SharedPreferences.Editor editor = preferences.edit();for (String key : mp.keySet()) {editor.putString(key, mp.get(key));}// 提交editor.commit();}private class HideTextWatcher implements TextWatcher {private EditText mView;private int mMaxLength;public HideTextWatcher(EditText v, int maxLength) {mView = v;mMaxLength = maxLength;}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {if(s.toString().length() == mMaxLength) {// 隐藏软键盘ViewUtil.hideOneInputMethod(LoginMainActivity.this, mView);}}}
}

 activity_login_forget.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!--这个显示的是具体的登录操作--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--设置这个文本是水平和垂直上是居中的gravity="center"--><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:text="@string/input_new_password"android:gravity="center"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><!--这里的background 引用的是以前写的 @drawable 里面提前写好的对输入的类型(数字) 以及长度进行限制提示的文字的颜色设置为 灰色的 md这个也是自己去写的--><EditTextandroid:id="@+id/et_password_first"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:background="@drawable/editext_selector"android:hint="@string/input_new_password_hint"android:inputType="numberPassword"android:maxLength="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="@dimen/common_font_size"/></LinearLayout><!--这个显示的是具体的登录操作--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--设置这个文本是水平和垂直上是居中的gravity="center"--><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:text="@string/confirm_new_password"android:gravity="center"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><!--这里的background 引用的是以前写的 @drawable 里面提前写好的对输入的类型(数字) 以及长度进行限制提示的文字的颜色设置为 灰色的 md这个也是自己去写的--><EditTextandroid:id="@+id/et_password_second"android:layout_width="0dp"android:layout_weight="1"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="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="@dimen/common_font_size"/></LinearLayout><!--这个显示的是让用户去输入密码--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="@dimen/item_layout_height"android:orientation="horizontal"><!--设置这个文本是水平和垂直上是居中的gravity="center"--><TextViewandroid:id="@+id/tv_verifycode"android:layout_width="wrap_content"android:layout_height="match_parent"android:text="@string/verifycode"android:gravity="center"android:textColor="@color/black"android:textSize="@dimen/common_font_size"/><!--这里用的是 相对布局 方便进行直接定位 忘记密码是要悬浮在最右边的--><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><!--这里的 alignParentEnd 相对的是 父的位置 在父盒子的最右边这里推荐的是 End 这个新更改的--><EditTextandroid: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="numberPassword"android:maxLength="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="@dimen/common_font_size" /><Buttonandroid:id="@+id/get_verifycode"android:layout_alignParentEnd="true"android:layout_width="wrap_content"android:layout_height="match_parent"android:textColor="@color/black"android:textSize="@dimen/common_font_size"android:text="@string/get_verifycode"/></RelativeLayout></LinearLayout><Buttonandroid: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>

LoginForgetActivity.java

package com.findyou.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import java.util.Random;public class LoginForgetActivity extends AppCompatActivity implements View.OnClickListener {private Button get_verifycode;private Button btn_confirm;private TextView et_password_first;private TextView et_password_second;private TextView et_verifycode;private String verifyCode;private ActivityResultLauncher<Intent> register;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login_forget);// 文本框里面的内容 为了后面的获取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);// 获取按钮 为了后面的监听事件get_verifycode = findViewById(R.id.get_verifycode);btn_confirm = findViewById(R.id.btn_confirm);// 设置监听事件get_verifycode.setOnClickListener(this);btn_confirm.setOnClickListener(this);}@Overridepublic void onClick(View v) {if(v.getId() == R.id.btn_confirm) { // 登录 确认if(!checkPassword() || !checkVerifyCode()) {return;}// 进行确认的操作// 要去跳转到登录界面 然后填充具体的数据// 进行相关操作后,设置返回结果Intent resultIntent = new Intent();Bundle bundle = new Bundle();// 获取传入的 phone 数据String phone = getIntent().getStringExtra("phone");// 随便带回一个密码都可以bundle.putString("password", et_password_first.getText().toString());bundle.putString("phone", phone);resultIntent.putExtras(bundle); // "返回的数据" 替换为实际要返回的值setResult(RESULT_OK, resultIntent);finish(); // 关闭 LoginForgetActivity 页面} else if(v.getId() == R.id.get_verifycode) { // 获取验证码// 生成6位的随机验证码verifyCode = String.format("%06d", new Random().nextInt(999999));// 弹出对话框 提示用户AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("密码可以忘,但验证码不能忘");builder.setMessage("本次验证码是" + verifyCode + ",请输入验证码");builder.setPositiveButton("好的", null);AlertDialog dialog = builder.create();dialog.show();}}/*** 对验证码的校验* @return* true 表示的是 校验正确* false 表示的是 校验错误*/private boolean checkVerifyCode() {String getVerifyCode = et_verifycode.getText().toString();if(getVerifyCode.isEmpty()) {showMessage("验证码不可为空");return false;}if(!getVerifyCode.equals(verifyCode)) {showMessage("验证码错误");return false;}return true;}/*** 用来对密码的校验* 调用它 然后根据返回值 来判断新密码的正确性* @return true 表示的校验正确 false 表示的是校验错误*/public boolean checkPassword() {String passwordFirst = et_password_first.getText().toString();String passwordSecond = et_password_second.getText().toString();if(passwordFirst == null || passwordSecond == null) {showMessage("请输入新密码");return false;}if(!passwordFirst.equals(passwordSecond)) {showMessage("两次密码不一致");return false;}return true;}/*** 提示用户具体的错误信息* @param message 具体信息*/public void showMessage(String message) {Toast.makeText(this,message, Toast.LENGTH_SHORT).show();}
}

string.xml

<resources><string name="app_name">Chapter5</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="login">登&#160; &#160; &#160;录</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">&#160;&#160; 验证码: </string><string name="input_verifycode">请输入验证码</string><string name="get_verifycode">获取验证码</string><string name="done">确&#160;&#160;&#160;定</string><string name="remember_password">记住密码</string>
</resources>

color.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="black">#FF000000</color><color name="white">#FFFFFFFF</color><!--自己去定义灰色 逆天--><color name="grey">#cccccc</color>
</resources>

Gitee源码(如果你感觉对你有帮助,就帮我star一下吧) 

FindYou/移动开发 

相关文章:

  • 基于大模型的大肠癌全流程预测与诊疗方案研究报告
  • Github 2025-05-25 php开源项目日报 Top10
  • 最好用的wordpress外贸主题
  • 反序列化之Wakeup方法绕过
  • Flink流水线集成Gravitino
  • Java反射详解
  • JVM 的内存模型
  • MySQL#秘籍#一条SQL语句执行时间以及资源分析
  • 超简单Translation翻译模型部署
  • 信奥赛CSP小学五年级动态规划入门
  • 【docker】--compose介绍
  • 高级特性实战:死信队列、延迟队列与优先级队列(二)
  • Go 语言基础 2 Func,流程控制
  • 【linux篇】系统世界跳跃的音符:指令
  • 嵌入式STM32学习—— 定时器中断(应用-利用定时器中断实现LED亮一秒灭一秒)
  • 并发编程知识点
  • MyBatis实战指南(二)如何实现小鸟图标与导入Teacher数据库表实战
  • 位图与布隆过滤器
  • RabbitMQ核心机制——延迟队列
  • win11 禁用/恢复 内置笔记本键盘(保证管用)
  • 导购网站制作/建站软件
  • 淘宝客做网站需要那些条件/深圳网站建设开发公司
  • 广州一起做网站/门户网站软文
  • 个人网页设计html加js代码/seo网站推广专员
  • 内部网站建设app/论坛seo网站
  • 女装网站建设规划/每日新闻播报