记录实践1Material Design风格的登录界面

先来个登录和注册吧


用了Material Design的风格

1.引路Material Design的库

implementation 'com.android.support:design:28.0.0'复制代码

修改主题文件

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="colorControlNormal">#D3D3D3</item>
    <item name="colorControlActivated">@color/colorPrimary</item>
</style>复制代码

?colorAccent 是哪里的颜色?是系统特定内容的颜色,类似的颜色statusBarColor、windowBackground,看这张图你就明白了

文本没有获取焦点的文字颜色:android:textColorHint

下划线没有获取焦点的颜色:colorControlNormal

下划线获取焦点的颜色:colorControlActivated

TextInputLayout取值:不需要通过获取TextView这样的string userNameText = userName.EditText.Text;

完整的登录界面代码:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="24dp"
        android:paddingRight="24dp"
        android:paddingTop="56dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="72dp"
            android:layout_gravity="center_horizontal"
            android:gravity="center"
            android:text="彩虹bbs"
            android:textColor="#000"
            android:textSize="20sp" />
        <!-- Email Label -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp">

            <EditText
                android:id="@+id/input_user"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="输入手机号或邮箱"
                android:inputType="textEmailAddress|phone"
                android:textColor="#D3D3D3" />
        </android.support.design.widget.TextInputLayout>
        <!-- Password Label -->
        <android.support.design.widget.TextInputLayout
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp">

            <EditText
                android:id="@+id/input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="输入密码"
                android:inputType="textPassword" />
        </android.support.design.widget.TextInputLayout>

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:background="@drawable/login_btn_selector"
            android:padding="12dp"
            android:enabled="false"
            android:text="登录"
            android:textColor="@color/color_white" />

        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/link_signup"
            android:clickable="true"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:gravity="center"
            android:text="没有账号?注册一个"
            android:textColor="#D3D3D3"
            android:textSize="16sp" />
    </LinearLayout>
</ScrollView>复制代码

用了MVP的设计模式,好像都有新的框架了

MVP 即模型-视图-呈现器

M:负责业务逻辑和实体模式

V:对应Activity,负责view的绘制和与用户交互

P:负责完成View于Model间的交互 

MVP模式通过Presenter实现数据和视图之间的交互, 简化了Activity的职责。 同时
即避免了View和Model的直接联系, 又通过Presenter实现两者之间的沟通。  

用户登录就是MVP的简单实现

结构图:

1.mode层

这里把数据存在了本地的sqlite中

  • 实体类存放用户数据
  • 接口要处理的业务逻辑
  • 接口实现类业务逻辑的具体实现

public class User {

    private String userName;
    private String passWord;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String getUserName() {
        return userName;
    }

    public String getPassWord() {
        return passWord;
    }

    @Override
    public String toString() {
        return "User{" +
                "password='" + passWord + '\'' +
                ", username='" + userName + '\'' +
                '}';
    }
    
}复制代码

封装了用户数据,便于传递

接口

public interface LoginModel {

    void login(User user, OnLoginFinishedListener onLoginFinishedListener);

}复制代码

其中OnLoginFinishedListener 是presenter层的接口, 方便实现回调presenter, 通
知presenter业务逻辑的返回结果 

接口实现类

public class LoginModelImpl implements LoginModel {

    @Override
    public void login(User user, final OnLoginFinishedListener onLoginFinishedListener) {

        final String userName = user.getUserName();
        final String passWord = user.getPassWord();

        new android.os.Handler().postDelayed(new Runnable() {
            boolean iserror = false;

            @Override
            public void run() {

                List<DataUser> users = DataSupport.select("usernum", "userpsd").where("usernum = ?", userName).limit(1).find(DataUser.class);

                if (users.size() > 0) {
                    String usernum = users.get(0).getUsernum();
                    String userpsd = users.get(0).getUserpsd();

                    if (!TextUtils.isEmpty(userName)) {
                        if (userName.equals(usernum)) {
                            iserror = false;
                        } else {
                            onLoginFinishedListener.usernameError(ConStant.USER_ERROR);
                            iserror = true;
                        }
                    } else {
                        onLoginFinishedListener.usernameError(ConStant.USER_ISEMPTY);
                        iserror = true;
                    }

                    if (!TextUtils.isEmpty(passWord)) {
                        if (passWord.equals(userpsd)) {
                            iserror = false;
                        } else {
                            onLoginFinishedListener.passwordError(ConStant.PASSWORD_ERROR);
                            iserror = true;
                        }
                    } else {
                        onLoginFinishedListener.passwordError(ConStant.PASSWORD_ISEMPTY);
                        iserror = true;
                    }

                } else {
                    onLoginFinishedListener.usernameError(ConStant.USER_ERROR);
                    iserror = true;

                }
                
                if (!iserror) {
                    onLoginFinishedListener.sucess();
                }
            }

        }, 1000);


    }
}
复制代码

 有非空判断,根据用户名从数据库中匹配密码正确则登录成功,或者登录失败。模拟登陆延迟1秒

2.View层

  • 接口,根据Activity的控件
  • 接口实现类,即登录Activity要实现接口

switch (e) {
    case ConStant.PASSWORD_ISEMPTY:
        input_password.setError(getString(R.string.password_isempty));
        break;
    case ConStant.PASSWORD_ERROR:
        input_password.setError(getString(R.string.password_error));
        break;
}复制代码

根据不同的错误代码有不同的错误提示

3.Presenter层

Presenter是用作Model和View之间交互的桥梁。 从上图的包结构图中可以看出,
Presenter包含内容:
①接口, 包含Presenter需要进行Model和View之间交互逻辑的接口, 以及上面提到
的Model层数据请求完成后回调的接口。
②接口实现类, 即实现具体的Presenter类逻辑。
//处理从model中传来的数据
public interface OnLoginFinishedListener {

    void usernameError(int errorCode);

    void passwordError(int errorCode);

    void sucess();
}复制代码
//model与view进行交互
public interface LoginPresenter {

    void validateCredentials(User user);
    void onDestroy();
}复制代码

登陆的Presenter 的接口, 实现类为LoginPresenterImpl, 完成登陆的验证, 以及销
毁当前view。 

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {

    private LoginView loginView;
    private LoginModel loginModel;

    public LoginPresenterImpl(LoginView loginView) {
        this.loginView = loginView;
        loginModel = new LoginModelImpl();
    }

    @Override
    public void validateCredentials(User user) {
        if (loginView != null) {
            loginView.showProgress();
        }
        if (loginModel != null) {
            loginModel.login(user, this);
        }

    }

    @Override
    public void onDestroy() {
        loginView = null;
    }

    @Override
    public void usernameError(int errorCode) {
        if (loginView != null) {
            loginView.hideProgress();
            loginView.setuserNameError(errorCode);
        }
    }

    @Override
    public void passwordError(int errorCode) {
        if (loginView != null) {
            loginView.hideProgress();
            loginView.setpassWordError(errorCode);
        }
    }

    @Override
    public void sucess() {
        if (loginView != null) {
            loginView.onSuccess();
        }
    } 复制代码

} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值