1.加依赖包

apply plugin: 'com.android.application'android {    compileSdkVersion 25    buildToolsVersion "26.0.1"    defaultConfig {        applicationId "com.example.myapplication"        minSdkVersion 15        targetSdkVersion 25        versionCode 1        versionName "1.0"        aaptOptions.cruncherEnabled = false        aaptOptions.useNewCruncher = false        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    //重点    dataBinding{        enabled = true    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {        exclude group: 'com.android.support', module: 'support-annotations'    })    //UI dependency    compile 'com.android.support:appcompat-v7:25.3.1'    compile 'com.android.support:design:25.3.1'    compile 'com.android.support:recyclerview-v7:25.3.1'    compile 'com.android.support:cardview-v7:25.3.1'    // rx android    compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'    compile 'io.reactivex:rxjava:1.0.16'    compile 'io.reactivex:rxandroid:1.0.1'    // gson    compile 'com.google.code.gson:gson:2.7'    // okhttp    compile 'com.squareup.okhttp3:okhttp:3.9.0'    compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'    compile 'com.github.simonpercic:oklog3:2.2.0'    // retrofit    compile 'com.squareup.retrofit2:retrofit:2.0.0'    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'    compile 'com.squareup.retrofit2:converter-gson:2.0.0'    // let the Retorfit work with Rxjava    compile 'com.jakewharton:butterknife:8.4.0'    compile 'com.android.support.constraint:constraint-layout:1.0.2'    testCompile 'junit:junit:4.12'}

2.新建APP类

import android.app.Application;public class App extends Application {    @Override    public void onCreate() {        super.onCreate();        initEnv();    }    //初始化app环境    private void initEnv(){        //初始化网络组件        APIFactory.init();    }}

3.AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.myapplication">    <application        android:name=".App"        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".LoginActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            intent-filter>        activity>    application>manifest>

4.在values中新建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="ValidatedInputTextLayout">        <attr name="autoValidate" format="boolean" />        <attr name="autoTrim" format="boolean" />        <attr name="isRequired" format="boolean" />        <attr name="requiredValidationMessage" format="string" />        <attr name="minLength" format="integer">            <enum name="zero" value="0" />        attr>        <attr name="maxLength" format="integer">            <enum name="indefinite" value="-1" />        attr>        <attr name="lengthValidationMessage" format="string" />        <attr name="regex" format="string" />        <attr name="regexValidationMessage" format="string" />    declare-styleable>resources>

5.新建ValidatedTextInputLayout类

import android.content.Context;import android.content.res.TypedArray;import android.support.design.widget.TextInputLayout;import android.text.Editable;import android.text.TextWatcher;import android.util.AttributeSet;import java.util.ArrayList;import java.util.List;public class ValidatedTextInputLayout extends TextInputLayout {    private List mValidators;    private boolean mAutoValidate = false;    private boolean mAutoTrimValue = false;    public ValidatedTextInputLayout(Context context) {        super(context);        initialize();    }    public ValidatedTextInputLayout(Context context, AttributeSet attrs) {        super(context, attrs);        initialize();        initializeCustomAttrs(context, attrs);    }    public ValidatedTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initialize();        initializeCustomAttrs(context, attrs);    }    private void initialize() {        if (!isInEditMode()) {            mValidators = new ArrayList<>();            this.post(new Runnable() {                @Override                public void run() {                    if (!getEditText().isInEditMode())                        initializeTextWatcher();                }            });        }    }    private void initializeCustomAttrs(Context context, AttributeSet attrs) {        if (!isInEditMode()) {            TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable                    .ValidatedInputTextLayout, 0, 0);            try {                mAutoTrimValue = typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_autoTrim,                        false);                mAutoValidate = typedArray.getBoolean(R.styleable                        .ValidatedInputTextLayout_autoValidate, false);                initRequiredValidation(context, typedArray);                initLengthValidation(context, typedArray);            } finally {                typedArray.recycle();            }        }    }    private void initRequiredValidation(Context context, TypedArray typedArray) {        if (typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_isRequired, false)) {            String errorMessage = typedArray.getString(R.styleable                    .ValidatedInputTextLayout_requiredValidationMessage);            if (errorMessage == null)                errorMessage = context.getString(R.string.default_required_validation_message);            addValidator(new RequiredValidator(errorMessage));        }    }    private void initLengthValidation(Context context, TypedArray typedArray) {        int minLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_minLength,                LengthValidator.LENGTH_ZERO);        int maxLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_maxLength,                LengthValidator.LENGTH_INDEFINITE);        if (!(minLength == LengthValidator.LENGTH_ZERO && maxLength == LengthValidator                .LENGTH_INDEFINITE)) {            String errorMessage = typedArray.getString(R.styleable                    .ValidatedInputTextLayout_lengthValidationMessage);            if (errorMessage == null) {                if (minLength == LengthValidator.LENGTH_ZERO) {                    errorMessage = context.getString(R.string.default_required_length_message_max, maxLength);                } else if (maxLength == LengthValidator.LENGTH_INDEFINITE) {                    errorMessage = context.getString(R.string                            .default_required_length_message_min, minLength);                } else {                    errorMessage = context.getString(R.string                            .default_required_length_message_min_max, minLength, maxLength);                }            }            addValidator(new LengthValidator(minLength, maxLength, errorMessage));        }    }    private void initializeTextWatcher() {        getEditText().addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                if (isAutoValidated()) validate();                else setError(null);            }            @Override            public void afterTextChanged(Editable s) {            }        });    }    public void clearValidators() {        mValidators.clear();        setErrorEnabled(false);    }    public void addValidator(BaseValidator pValidator) {        mValidators.add(pValidator);        setErrorEnabled(true);    }    public void autoValidate(boolean flag) {        mAutoValidate = flag;    }    public boolean isAutoValidated() {        return mAutoValidate;    }    public void autoTrimValue(boolean flag) {        mAutoTrimValue = flag;    }    public boolean isAutoTrimEnabled() {        return mAutoTrimValue;    }    public boolean validate() {        boolean status = true;        String text = getValue();        for (IValidator validator : mValidators) {            if (!validator.isValid(text)) {                setError(validator.getErrorMessage());                status = false;                break;            } else {                setError(null);            }        }        return status;    }    public String getValue() {        if (isAutoTrimEnabled()) return getEditText().getText().toString().trim();        else return getEditText().getText().toString();    }}

6.新建BaseValidator类

import android.support.annotation.NonNull;public abstract class BaseValidator implements IValidator {    protected String mErrorMessage;    public BaseValidator(@NonNull String pErrorMessage) {        setErrorMessage(pErrorMessage);    }    @Override    public abstract boolean isValid(String pText);    @Override    public void setErrorMessage(@NonNull String pErrorMessage) {        mErrorMessage = pErrorMessage;    }    @Override    public String getErrorMessage() {        return mErrorMessage;    }}

7.新建LengthValidator类

import android.support.annotation.NonNull;public class LengthValidator extends BaseValidator {    public static final int LENGTH_INDEFINITE = -1;    public static final int LENGTH_ZERO = 0;    private int mMinimumLength = LENGTH_ZERO;    private int mMaximumLength = LENGTH_INDEFINITE;    public LengthValidator(@NonNull String pErrorMessage) {        super(pErrorMessage);    }    public LengthValidator(int pMaximumLength, @NonNull String pErrorMessage) {        super(pErrorMessage);        mMaximumLength = pMaximumLength;    }    public LengthValidator(int pMinimumLength, int pMaximumLength, @NonNull String pErrorMessage) {        super(pErrorMessage);        mMinimumLength = pMinimumLength;        mMaximumLength = pMaximumLength;    }    @Override    public boolean isValid(String pText) {        int length = pText.length();        if (getMaximumLength() == LENGTH_INDEFINITE) {            return length >= getMinimumLength();        } else {            return (length >= getMinimumLength() && length <= getMaximumLength());        }    }    public void setMinimumLength(int pMinimumLength) {        mMinimumLength = pMinimumLength;    }    public void setMaximumLength(int pMaximumLength) {        mMaximumLength = pMaximumLength;    }    public int getMinimumLength() {        return mMinimumLength;    }    public int getMaximumLength() {        return mMaximumLength;    }}

8.新建RequiredValidator类

public class RequiredValidator extends BaseValidator {    public RequiredValidator(String pErrorMessage) {        super(pErrorMessage);    }    @Override    public boolean isValid(String pText) {        return !pText.isEmpty();    }}

9.新建IValidator接口

public interface IValidator {    boolean isValid(String pText);    void setErrorMessage(String pErrorMessage);    String getErrorMessage();}

10.新建APIFactory类

import com.github.simonpercic.oklog3.OkLogInterceptor;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.google.gson.JsonArray;import com.google.gson.JsonDeserializationContext;import com.google.gson.JsonDeserializer;import com.google.gson.JsonElement;import com.google.gson.JsonParseException;import com.lemner.hation.ykbb.BuildConfig;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.Collections;import java.util.List;import okhttp3.OkHttpClient;import okhttp3.logging.HttpLoggingInterceptor;import retrofit2.Retrofit;import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;import retrofit2.converter.gson.GsonConverterFactory;public class APIFactory {    private static APIService API_SERVICE;    private static final String BASE_URL = "/*服务器网址*/";    private static final String PREFIX_BASE_URL = BASE_URL+"";    public static final String PREFIX_BASE_IMG_URL = BASE_URL+"";    private static Gson sGson;    private static final int DEFAULT_TIMEOUT = 5;    public static void init(){        OkLogInterceptor okLogInterceptor =  OkLogInterceptor.builder().useAndroidLog(true).build();        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();        logging.setLevel(HttpLoggingInterceptor.Level.BODY);        OkHttpClient.Builder build=new OkHttpClient.Builder();        //if model is debug add a interceptor        if (BuildConfig.DEBUG) {            build .addInterceptor(okLogInterceptor);        }        OkHttpClient client = build.build();        API_SERVICE = new Retrofit.Builder()                .baseUrl(PREFIX_BASE_URL)                .client(client)                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                .addConverterFactory(GsonConverterFactory.create(buildGson()))                .build().create(APIService.class);    }    public static APIService getApiService() {        return API_SERVICE;    }    private static Gson buildGson() {        if(sGson==null){            sGson = new GsonBuilder().setPrettyPrinting().setLenient().registerTypeHierarchyAdapter(List.class, new JsonDeserializer>() {                @Override                public List<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {                    if (json.isJsonArray()) {                        JsonArray array = json.getAsJsonArray();                        Type itemType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];                        List list = new ArrayList<>();                        for (int i = 0,size=array.size(); i < size; i++) {                            JsonElement element = array.get(i);                            Object item = context.deserialize(element, itemType);                            list.add(item);                        }                        return list;                    } else {                        //和接口类型不符,返回空List                        return Collections.EMPTY_LIST;                    }                }            }).create();        }        return sGson;    }}

11.新建LoginBean类

package com.example.myapplication;public class LoginBean{    private String userid;    public String getUserid() {        return userid;    }    public void setUserid(String userid) {        this.userid = userid;    }}

12.新建APIService类

package com.example.myapplication;import retrofit2.http.GET;import retrofit2.http.Query;import rx.Observable;public interface APIService {    //登录    @GET("userLogin.do")    Observable login(            @Query("username") String username,            @Query("userpass") String userpass    );}

13.新建activity_login.xml文件

<?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"    xmlns:tools="http://schemas.android.com/tools"    xmlns:validation="http://schemas.android.com/apk/res-auto">    <data>        <variable            name="loginViewModel"            type="com.example.myapplication.LoginViewModel" />    data>    <LinearLayout        android:orientation="vertical"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:context=".LoginActivity">        <com.example.myapplication.ValidatedTextInputLayout            app:errorTextAppearance="@style/Theme.AppCompat"            android:id="@+id/validate_et_username"            android:layout_width="match_parent"            android:layout_height="wrap_content"            validation:autoTrim="true"            validation:isRequired="true">            <EditText                android:id="@+id/et_username"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:hint="请输入用户名"/>        com.example.myapplication.ValidatedTextInputLayout>        <com.example.myapplication.ValidatedTextInputLayout            app:errorTextAppearance="@style/Theme.AppCompat"            android:id="@+id/validate_et_password"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginLeft="30dp"            android:layout_marginRight="30dp"            validation:autoTrim="true"            validation:isRequired="true">            <EditText                android:id="@+id/et_password"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:hint="请输入密码"/>        com.example.myapplication.ValidatedTextInputLayout>        <Button            android:id="@+id/bt_login"            android:layout_width="100dp"            android:layout_height="40dp"            android:text="登录"            android:onClick="@{loginViewModel::onClickEvent}"/>    LinearLayout>layout>

14.新建LoginViewModel类

import android.content.Context;import android.view.View;import android.widget.Toast;import rx.Subscriber;import rx.android.schedulers.AndroidSchedulers;import rx.schedulers.Schedulers;public class LoginViewModel{    protected Context context;    private LoginViewModelContract.LoginView loginView;    public LoginViewModel(LoginViewModelContract.LoginView loginView ,Context context) {        this.context=context;        this.loginView = loginView;    }    public void onClickEvent(View view) {        switch (view.getId()) {            case R.id.bt_idcode:                loginView.postLogin();                break;        }    }    public void destroy() {    }    public void postLogin(String username , String pasword){        APIFactory.getApiService().login(username,pasword)                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Subscriber() {                    @Override                    public void onCompleted() {                    }                    @Override                    public void onError(Throwable e) {                        Toast.makeText(context, "网络连接不畅",Toast.LENGTH_SHORT).show();                    }                    @Override                    public void onNext(LoginBean loginBean) {                        if (true/*没写*/){                            //context.startActivity(new Intent(context,MainActivity.class));//成功后跳转                        }else {                            Toast.makeText(context , "账号或密码错误!",Toast.LENGTH_SHORT).show();                        }                    }                });    }}

15.新建LoginViewModelContract接口

public interface LoginViewModelContract {    interface LoginView{        void showLoadingDialog();        void dismissLoadingDialog();        void postLogin();    }}

16.新建LoginActivity类

import android.app.ProgressDialog;import android.databinding.DataBindingUtil;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.view.View;import com.example.myapplication.databinding.ActivityLoginBinding;import butterknife.ButterKnife;public class LoginActivity extends AppCompatActivity implements LoginViewModelContract.LoginView{    private LoginViewModel loginViewModel;    private ActivityLoginBinding activityLoginBinding;    private ProgressDialog mProgressDialog;    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setView();        initView();        ButterKnife.bind(this);    }    public void initView() {    }    public View setView() {        activityLoginBinding = DataBindingUtil.setContentView(this , R.layout.activity_login);        loginViewModel = new LoginViewModel(this,LoginActivity.this);        activityLoginBinding.setLoginViewModel(loginViewModel);        return activityLoginBinding.getRoot();    }    public void onViewDestroy() {        loginViewModel.destroy();    }    public void showLoadingDialog() {        mProgressDialog.show();    }    public void dismissLoadingDialog() {        mProgressDialog.dismiss();    }    public void postLogin() {        loginViewModel.postLogin(activityLoginBinding.etUsername.getText().toString() , activityLoginBinding.etPassword.getText().toString());    }}

更多相关文章

  1. Android之获取Android唯一ID
  2. Android(安卓)5.0 Input初始化
  3. 博客技术资料整理
  4. android TabHost小结
  5. android TabHost小结
  6. Android之Audio初探
  7. Android的Camera系统结构
  8. 系出名门Android(9) - 数据库支持(SQLite),
  9. Android图形系统的底层实现

随机推荐

  1. android获取网络类型
  2. Android版本和API level对应关系
  3. 【Android】数据存储之Network
  4. Android完整弹窗界面
  5. android读取本地网页
  6. Android语法清单
  7. Android的WebView如何播放视频
  8. Android(安卓)CTS one function
  9. Android(安卓)Studio下多渠道打包
  10. Android(安卓)机顶盒Mobx 对接xbmc