【Android应用开发之前端——简易App登录页面】

1.完成登录页面布局

各家App的登录页面大同小异,要么是用户名和密码组合登录,要么是手机号和验证码组合登录。如果要做的更好一点,就要提供忘记密码与记住密码等功能。我们的App登录项目把这些功能综合一下,都呈现到页面上。先将效果图奉上:

使用密码登录:
使用密码登录
使用验证码登录:
使用验证码登录
修改密码:
修改密码
完成以上界面用到了以下新控件:
● 单选按钮RadioButton:用来区分是密码登录还是验证码登录。
● 下拉框Spinner:用于区分用户类型是个人用户还是公司用户。
● 编辑框EditText:用来输入手机号码和密码。
● 相对布局RelativeLayout:指定手机号码的编辑框放在手机号码TextView的右边,这里使用线性布局LinearLayout也可以。
● 框架布局FrameLayout:忘记密码的按钮与密码输入框叠加。为了使页面更美观这里仍采用线性布局。

布局具体实现如下:

<?xml version="1.0" encoding="utf-8"?>
<!--登录页面-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="20dp">
        <RadioGroup
            android:id="@+id/rg_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
        <RadioButton
            android:id="@+id/rb_password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="70dp"
            android:text="密码登录"/>
        <RadioButton
            android:id="@+id/rb_vertifyCode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="验证码登录" />
        </RadioGroup>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="20dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是:"
            android:paddingLeft="32dp"/>
        <Spinner
            android:id="@+id/spinner"
            android:layout_marginLeft="80dp"
            android:layout_height="wrap_content"
            android:layout_width="150dp"
            android:entries="@array/spinner_string"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="20dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="4dp"
            android:text="手机号码:"/>
        <EditText
            android:id="@+id/et_phone"
            android:layout_width="236dp"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="20dp">
        <TextView
            android:id="@+id/tv_password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="4dp"
            android:text="登录密码:"/>
        <EditText
            android:id="@+id/et_password"
            android:layout_width="236dp"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/btn_forget"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="忘记密码"/>
    </LinearLayout>
    <Button
        android:id="@+id/btn_login"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--修改密码页面-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_marginTop="10dp"
        android:layout_marginLeft="4dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="输入新密码:"/>
    <EditText
        android:id="@+id/et_password_first"
        android:layout_width="236dp"
        android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:layout_marginTop="10dp"
        android:layout_marginLeft="4dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确认新密码:"/>
        <EditText
            android:id="@+id/et_password_second"
            android:layout_width="236dp"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="4dp">
        <TextView
            android:layout_marginLeft="28dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="验证码:"/>
        <EditText
            android:id="@+id/et_verifyCode"
            android:layout_width="142dp"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/btn_verifyCode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取验证码"/>
    </LinearLayout>
    <Button
        android:id="@+id/btn_confirm"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="确认"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--Spinner中的值-->
<resources>
    <string-array name="spinner_string">
        <item>个人用户</item>
        <item>公司用户</item>
    </string-array>
</resources>

2.完成业务逻辑

找回密码的页面挺简单,主要问题是两个页面之间的跳转有哪些注意事项?页面跳转肯定要传递参数,一般唯一标识的手机号码要传过去,不然下一个页面不知道要为哪个手机号码需要改密码;新密码也要传回去,不然上一个页面不知道密码被改成什么了。可以看出页面之间的数据传递是该项目的重点

另外,有一个细微的用户体验问题:用户会去找回密码,肯定是发现输入的密码不对。修改完密码回到登录页面时,密码输入框里还是原来错误的密码,此时用户清空错误密码才能输入新密码。我们的App想要用户觉得好用,就得急用户之所急、想用户之所想,像之前错误密码的情况应当由App再返回登录页面时自动清空原来错误的密码。自动清空的操作放在registerForActivityResult方法中处理是一个方法,但这样处理有一个问题,如果用户直接按返回键回到登录页面,registerForActivityResult方法发现数据为空就不会处理。

其实这个问题并不难,我们只需重写onRestart方法(确保是返回页面),在方法内部加上清空密码框的处理即可。这样一来,无论用户是修改完密码回到登录页,还是点击返回键回到登录页,App都会自动清空密码框。

使用验证码登录时,App要向用户手机发送短信验证码,但发送短信需要服务器支持,所以这里暂时使用随机数模拟验证码,然后以对话框AlertDialog的形式在界面上提示用户。

3.根据逻辑编写功能(代码示例)

//LoginMainActivity
package com.example.exercise;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class LoginMainActivity extends AppCompatActivity implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {
    private EditText et_phone;
    private EditText et_password;
    private RadioButton rb_password;
    private RadioButton rb_verifyCode;
    private Button btn_forget;
    private String mVerifyCode;
    private String mPassword;
    private String phone;
    private String mType;
    private Spinner type_spinner;
    private String[] type;
    private ActivityResultLauncher<Intent> register;
    private TextView tv_password;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        btn_forget = findViewById(R.id.btn_forget);
        rb_password = findViewById(R.id.rb_password);
        rb_verifyCode = findViewById(R.id.rb_vertifyCode);
        tv_password = findViewById(R.id.tv_password);
        //获取spinner中数组的值
        type_spinner = findViewById(R.id.spinner);
        type = getResources().getStringArray(R.array.spinner_string);
        type_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                mType = type[position];
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
        findViewById(R.id.btn_forget).setOnClickListener(this);
        findViewById(R.id.btn_login).setOnClickListener(this);
        findViewById(R.id.rb_vertifyCode).setOnClickListener(this);
        RadioGroup rg_login = findViewById(R.id.rg_login);
        rg_login.setOnCheckedChangeListener(this);
        //获取下个页面返回的数据
        register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if(result != null){
                Intent intent = result.getData();
                if(intent != null && result.getResultCode() == Activity.RESULT_OK)
                mPassword = intent.getStringExtra("new_password");
            }
        });
    }

    public void onClick(View v){
        et_phone = findViewById(R.id.et_phone);
        et_password = findViewById(R.id.et_password);
        phone = et_phone.getText().toString();
        if(v.getId() == R.id.btn_forget){
            if(phone == null || phone.length() < 11){
                Toast.makeText(this, "请输入正确的手机号", Toast.LENGTH_SHORT).show();
                return;
            }
            if(rb_password.isChecked() == true){
                //给下个页面传递数据
                Intent intent = new Intent(this, LoginForgetActivity.class);
                intent.putExtra("phone", phone);
                register.launch(intent);
            } else if(rb_verifyCode.isChecked() == true){
                mVerifyCode = String.format("%06d", (int)(Math.random() * 1000000 % 10000000));
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("请记住验证码");
                builder.setMessage("手机号" + phone +",本次验证码是" + mVerifyCode + ",请输入验证码");
                builder.setPositiveButton("好的", null);
                AlertDialog alert = builder.create();
                alert.show();
            }
        } else if(v.getId() == R.id.btn_login){
            if(phone == null || phone.length() < 11){
                Toast.makeText(this, "请输入正确的手机号", Toast.LENGTH_SHORT).show();
                return;
            }
            if(rb_password.isChecked() == true){
                if(et_password.getText().toString().equals(mPassword) != true){
                    Toast.makeText(this, "请输入正确的密码", Toast.LENGTH_SHORT).show();
                    return;
                } else {
                    loginSuccess();
                }
            } else {
                if(et_password.getText().toString().equals(mVerifyCode) != true){
                    Toast.makeText(this, "验证码错误,请重新输入!", Toast.LENGTH_SHORT).show();
                    return;
                } else {
                    loginSuccess();
                }
            }
        }
    }
    @Override
    protected void onRestart(){
        et_password.setText("");
        super.onRestart();
    }
    private void loginSuccess(){
        String desc = String.format("您的手机号码是%s,类型是%s。恭喜你通过登陆验证!", et_phone.getText().toString(), mType);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("登录成功");
        builder.setMessage(desc);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                onRestart();
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        switch (checkedId){
            case R.id.rb_password:
                tv_password.setText("登录密码:");
                btn_forget.setText("忘记密码");
                break;
            case R.id.rb_vertifyCode:
                tv_password.setText("  验证码  :");
                btn_forget.setText("获取验证码");
                break;
        }
    }
}
//LoginForgetActivity
package com.example.exercise;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class LoginForgetActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText et_password_first;
    private EditText et_password_second;
    private EditText et_verifyCode;
    private String mVerifyCode;
    private String mPhone;

    @Override
    protected 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);
        findViewById(R.id.btn_confirm).setOnClickListener(this);
        findViewById(R.id.btn_verifyCode).setOnClickListener(this);
        mPhone = getIntent().getStringExtra("phone");
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.btn_verifyCode){
            if(mPhone == null || mPhone.length() < 11){
                Toast.makeText(this, "请输入正确的手机号", Toast.LENGTH_SHORT).show();
                return;
            }
            mVerifyCode = String.format("%06d", (int)(Math.random() * 1000000 % 1000000));
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("请记住验证码");
            builder.setMessage("手机号" + mPhone + ",本次验证码是" + mVerifyCode + ",请输入验证码");
            builder.setPositiveButton("好的", null);
            AlertDialog alert = builder.create();
            alert.show();
        } else if(v.getId() == R.id.btn_confirm){
            String password_first = et_password_first.getText().toString();
            String password_second = et_password_second.getText().toString();
            if(password_first == null || password_first.length() < 6 || password_second == null || password_second.length() < 6){
                Toast.makeText(this, "请输入正确的新密码", Toast.LENGTH_SHORT).show();
                return;
            } else if(password_first.equals(password_second) != true){
                Toast.makeText(this, "两次输入的新密码不一致", Toast.LENGTH_SHORT).show();
                return;
            } else if(et_verifyCode.getText().toString().equals(mVerifyCode) != true){
                Toast.makeText(this, "请输入正确的验证码", Toast.LENGTH_SHORT).show();
                return;
            } else {
                EditSuccess();
                //Toast.makeText(this, "密码修改成功", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();
                intent.putExtra("new_password", password_first);
                setResult(Activity.RESULT_OK, intent);
            }
        }
    }
    private void EditSuccess(){
        String desc = String.format("修改密码成功!点击”确定“按钮返回上个页面");
        android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
        builder.setTitle("修改成功");
        builder.setMessage(desc);
        builder.setPositiveButton("确认返回", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                finish();
            }
        });
        android.app.AlertDialog alert = builder.create();
        alert.show();
    }
}

简易App登录页面到这里就完成了!

  • 36
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wistain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值