今天我們拆解一下專車的意見反饋,涉及到TextWatcher監聽、特殊字符過濾Pattern等知識點和hideInputMethod收鍵盤、setEnabled按鈕使能、shape圓角矩形、maxLength最大長度、hint默認提示、String.format優化效率等細節,如圖是我們開發時的標注圖,聚焦到每一像素,對UI敏感,練就一雙火眼金睛···
現在我們一一拆解這些細節和知識點,絕不僅僅是輸入提交看上去這么簡單。
交互層面
1.通過TextWatcher監聽,
1.1在onTextChanged中處理,無內容時按鈕置灰,有內容時按鈕高亮;
1.2在afterTextChanged中處理,提示用戶還可輸入的字數;
2.在onClick中處理點擊事件,點擊提交按鈕后,進行下一步操作:
2.1通過正則和String API過濾特殊字符,防止注入攻擊;
2.2將意見通過網絡傳回后臺;
2.2.1如果網絡請求成功
Toast提示“提交成功”--》通過系統服務InputMethodManager收鍵盤--》finish()關閉當前頁面,回到上一頁面
2.2.2如果網絡請求失敗
Toast提示“提交失敗”--》保留鍵盤并停在當前頁面
視覺層面
UI設計師專業把控+前端工程師經驗直覺,從整體到局部,一個個像素、一個個樣式的推敲。
拆解輸入框,不僅僅是一個輸入框。
如圖,最外層一個圓角矩形樣式,垂直分布的LinearLayout,里面包著一個EditText輸入框和一個TextView動態顯示字數。
安全層面
通過Pattern進行特殊字符過濾,防止注入攻擊做好安全防范。
Coding實戰
1.通過TextWatcher監聽,為EditText輸入框添加監聽事件。
mContentEt.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) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
1.1在onTextChanged中處理,無內容時按鈕置灰,有內容時按鈕高亮;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.isEmpty(mContentEt.getText().toString())) {
mCommitTv.setEnabled(false);
} else {
mCommitTv.setEnabled(true);
}
}
1.2在afterTextChanged中處理,提示用戶還可輸入的字數;
1.3在afterTextChanged中處理,字數到達上限后進行攔截并給出提示。
@Override
public void afterTextChanged(Editable s) {
int length = mContentEt.getText().length();
if (length > MAXNUM) {
Toast.makeText(mContext, getString(R.string.input_feedback_content_long), Toast.LENGTH_SHORT).show();
String text = mContentEt.getText().toString()
.substring(0, MAXNUM - 1);
mContentEt.setText(text);
length = MAXNUM;
}
int left = MAXNUM - length;
mWatchWordsTv.setText(String.format(getResources().getString(R.string.default_feedback_words), Integer.toString(left)));
}
2.在onClick中處理點擊事件,點擊提交按鈕后,進行下一步操作:
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.commit_tv_feedback:
~~~
default:
break;
}
}
2.1通過正則和String API過濾特殊字符,防止注入攻擊;
/**
* 過濾特殊字符
*/
public static String stringFilter(String str) {
if (TextUtils.isEmpty(str)) {
return "";
}
String regEx = "[<>'\"]";
str = str.replaceAll(" ", "").replaceAll("&", "")
.replaceAll("#160;", "").replaceAll("<", "")
.replaceAll(">", "").replaceAll(""", "")
.replaceAll("<", "").replaceAll(">", "")
.replaceAll("&", "").replaceAll(""", "");
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
2.2將意見通過網絡傳回后臺;
以后專門拿一篇文章講Volley,在這不做實現。
2.2.1如果網絡請求成功
Toast提示“提交成功”--》通過系統服務InputMethodManager收鍵盤--》finish()關閉當前頁面,回到上一頁面
Toast.makeText(mContext, getString(R.string.feedback_success), Toast.LENGTH_SHORT).show();
hideInputMethod();
finish();
/**
* 隱藏軟鍵盤
*/
public void hideInputMethod() {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null && this.getCurrentFocus() != null) {
imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
}
2.2.2如果網絡請求失敗
Toast提示“提交失敗”--》保留鍵盤并停在當前頁面
至此,主流程拆解完畢。
關于shape圓角矩形、maxLength最大長度、hint默認提示、String.format優化效率等細節可以參考源碼,在此不一一展開了。
最后效果如圖,畫面有點不流暢,大家最好自己動手試試哈。
原創不易,轉載請注明出處哈。
權興權意
產品可以更優雅~
項目源代碼,歡迎提建議(Star和Fork)。
項目實戰:優雅的實現專車意見反饋 · HXQWill/QuanStudy@f489374 https://github.com/HXQWill/QuanStudy/commit/f489374d0e3f7ad3e0b9b2831f63ab96bec9d7ea