android最常見的UI之一,登錄遍佈各大APP,這麼easy的東西還是要寫寫,主要是介紹下:密碼的顯示與隱藏,用戶名和密碼錶單的網絡請求和提交方式等細節問題。看一個簡單的效果:
一,乾言
界面元素,logo,用戶名,密碼,登錄按鈕,底部兩個按鈕,訪問有loading效果。
點擊登錄,獲取用戶和密碼,簡單校驗,發送網絡請求,然後校驗請求結果,有異常做響應處理。
二,xml佈局,view
佈局代碼,有點多,直接貼出來。需要的對應改吧改吧。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center"
android:background="@drawable/login_bg">
<!--main content-->
<LinearLayout
android:id="@+id/ll_login_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_centerVertical="true"
android:orientation="vertical">
<!--logo-->
<ImageView
android:id="@+id/iv_logo"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="30dp"
android:src="@drawable/logo_oair" />
<!--login username-->
<LinearLayout
android:id="@+id/ll_login_user"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:background="@drawable/input_bg"
android:layout_gravity="center"
android:orientation="horizontal"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:background="@drawable/icon_user" />
<EditText
android:id="@+id/et_username"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="5"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:singleLine="true"
android:ellipsize="middle"
android:background="@android:color/transparent"
android:text="@string/login_username_default"
android:editable="false"
android:textColor="@color/white" />
<ImageView
android:id="@+id/iv_show_name"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="2dp"
android:scaleType="center"
android:clickable="true"
android:src="@drawable/icon_down" />
</LinearLayout>
<!--login password-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:background="@drawable/input_bg"
android:layout_gravity="center"
android:orientation="horizontal"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:background="@drawable/icon_pwd"
/>
<EditText
android:id="@+id/et_password"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="5"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:focusable="true"
android:inputType="textPassword"
android:background="@android:color/transparent"
android:textColor="@color/white" />
<ImageView
android:id="@+id/iv_hidden_pwd"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="2dp"
android:scaleType="center"
android:clickable="true"
android:src="@drawable/icon_hidden" />
</LinearLayout>
<!--login btn-->
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="@string/login_btn"
android:textSize="20sp"
android:textColor="@drawable/text_select"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/btn_login_bg" />
</LinearLayout>
<!--bottom btn-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_below="@id/ll_login_body">
<TextView
android:id="@+id/tv_login_contactus"
android:text="@string/login_about"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:textSize="16sp"
android:padding="10dp"
android:clickable="true"
android:textColor="#FFF" />
<TextView
android:id="@+id/tv_login_guest"
android:text="@string/login_guest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:textSize="16sp"
android:padding="10dp"
android:clickable="true"
android:textColor="#FFF" />
</RelativeLayout>
<ProgressBar
android:id="@+id/pb_login"
style="@style/MyCircleProgressBar"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:indeterminateDuration="700"/>
</RelativeLayout>
註冊view和事件
findViewById的事情就別自己一個個複製了,使用ButterKnife依賴注入view和事件,類似的框架很多。例如:
@Bind(R.id.et_username)
public EditText et_username;
@Bind(R.id.et_password)
public EditText et_password;
在onCreate方法中,注入:
ButterKnife.bind(this);
之前犯過錯誤,@Bind view需要使用public修飾屬性。
Error:(68, 23) 錯誤: @Bind fields must not be private or static. (com.oair.oair_client.LoginActivity.iv_logo)
三,activity登錄邏輯
獲取edittext中的value,判斷用戶名,密碼是否爲空,如果ok就進行網絡請求,post後臺登錄接口。我用retrofit+okhttp+RxJava/RxAndroid實現登錄,json用內部封裝的gson解析。
@OnClick(R.id.btn_login)
public void LoginOair(){
Login();
}
//Login 管理員登錄
public void Login() {
// 點擊登錄的時候 拿到用戶名和密碼的值
username = et_username.getText().toString();
password = et_password.getText().toString();
//判斷密碼是否爲空
if (StringUtils.isEmpty(password)) {
showDialog(context.getResources().getString(R.string.dialog_pwd_empty));
} else {
//驗證登錄是否成功
postLogin();
}
}
private void postLogin() {
pb_login.setVisibility(View.VISIBLE);
MyRetrofitUtils.init().loginOair(password, new Subscriber<OairResponse>() {
@Override
public void onCompleted() {
pb_login.setVisibility(View.GONE);
}
@Override
public void onError(Throwable e) {
checkLocalPwd();
LogUtils.debug(TAG,"error "+e.toString());
pb_login.setVisibility(View.GONE);
}
@Override
public void onNext(OairResponse oairResponse) {
LogUtils.debug(TAG,oairResponse.toString());
if (oairResponse.result == MyConstant.RESULT_SUCCESS){
enterMainActivity();
}else{ showDialog(context.getResources().getString(R.string.dialog_pwd_error));
}
}
});
}
不會用?可以使用你喜歡的網絡訪問方式,OKHTTP,HTTPUrlConnection,xUtils,volley都行。或者請看我的另外一篇文章,點擊打開:
RxJava+Retrofit+Gson實現網絡請求
四,隱藏和顯示密碼
EditText控件本身就封裝好了顯示與隱藏的方法,可以方便地將文本置爲可見,或者隱藏。
//切換輸入密碼的模式,明文or密文顯示
private boolean isHidden=true;
@OnClick(R.id.iv_hidden_pwd)
public void hiddenPassword() {
if (isHidden) {
//設置EditText文本爲可見的
et_password.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
} else {
//設置EditText文本爲隱藏的
et_password.setTransformationMethod(PasswordTransformationMethod.getInstance());
}
isHidden = !isHidden;
et_password.postInvalidate();
//切換後將EditText光標置於末尾
CharSequence charSequence = et_password.getText();
if (charSequence!=null) {
Spannable spanText = (Spannable) charSequence;
Selection.setSelection(spanText, charSequence.length());
}
}
五,輸入法彈出,佈局調整
有時候手機頻幕小,彈出輸入法框,可能會將edittext控件擋住,影響輸入。這時候我們可以配置下activity。
<activity
android:name="com.xx.client.LoginActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/title_activity_login"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
重點就是android:configChanges和android:windowSoftInputMode的屬性,讓activity自動調整界面,輸入法位於輸入框的下方。
六,總結
看似簡單的一個功能,細看起來,知識點還是挺多的。這裏面還有很多東西沒有列出,比如用戶名下拉選擇一個用戶登錄,登錄保存狀態下次免登錄,cookie的使用等。
未完待續,歡迎交流,杜乾,Dusan,Q 291902259。