編輯:關於Android編程
有一個需求是這樣的,頁面上有一個輸入框,供用戶輸入手機號碼,如果通訊錄裡面存在這個號碼,會自動把名字追加到號碼後面。這個需求變態的地方在於,假如用一個EditText+TextView,那麼不好控制二者之間的距離,就算是做了各種適配,但是用戶可以設置系統的字體,仍然顯示很難看!沒辦法,之好在一個EditText裡面來做,讓號碼是可編輯的,名字是自動追加上的。
MainActivity.java:
public class MainActivity extends Activity {
private EditText edittext;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View rootView = this.findViewById(R.id.rootview);
edittext = (EditText) this.findViewById(R.id.edittext1);
//限定只能輸入數字
edittext.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
//可以獲取焦點
button = (Button)this.findViewById(R.id.button1);
button.setFocusable(true);
button.setFocusableInTouchMode(true);
// 空白處點擊,隱藏軟鍵盤
rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hideSoftInput();
}
});
// 一旦獲取焦點,設置光標位置
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
String mobile = getMobile(edittext.getText().toString());
setCursorPosition(mobile.length());
}
}
});
// 返回true,手動處理touch事件,即使edittext獲取了焦點,也不會自動彈出軟鍵盤,要手動彈出
// http://stackoverflow.com/questions/10263384/android-how-to-get-text-position-from-touch-event
edittext.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + edittext.getScrollX();
int offset = layout.getOffsetForHorizontal(0, x);
if(offset >= 0 && offset < 11){
edittext.setSelection(offset);
}else if(offset >= 11){
edittext.setSelection(11);
}
showSoftInput();
}
return true;
}
});
edittext.addTextChangedListener(new TextWatcher() {
private String preText;
@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) {
String mobile = getMobile(s.toString());
String nowtext = buildEditTextContent(mobile);
if (nowtext.equals(preText)) {
return;
}
// 計算當前的光標位置
int offset = calCursorOffset(preText, nowtext);
// 一定要在setTest之前設置preText,否則會StackOverflow
preText = nowtext;
edittext.setText(nowtext);
// 文字發生變化,重新設置光標,否則會跑到最前面
setCursorPosition(offset);
if (mobile.length() == 11) {
hideSoftInput();
}
}
});
edittext.setText("15012341234");
}
private void hideSoftInput(){
edittext.requestFocus();
hideKeyboard();
button.requestFocus();
}
private void showSoftInput(){
edittext.requestFocus();
showKeyboard(edittext);
}
private void setCursorPosition(int offset){
edittext.setSelection(offset);
}
private String getMobile(String text){
if(text == null || text.length() <= 0){
return "";
}
String arr[] = text.split("\\s");
String mobile = arr[0];
return mobile;
}
private String buildEditTextContent(String mobile){
String name = getName(mobile);
String text = mobile + (name == null ? "" : " " + name);
return text;
}
private int calCursorOffset(String pre, String now){
if(isBlank(pre) && isBlank(now)){
return 0;
}else if(!isBlank(pre) && !isBlank(now)){
for(int i=0; i 11 ? 11 : now.length();
}
// 業務方法,聯系人數據
private Map data;
private String getName(String mobile) {
if (data == null) {
data = contactData();
}
return data.get(mobile);
}
private Map contactData() {
Map data = new HashMap();
data.put("15012341234", "張三");
data.put("15112341234", "李四");
data.put("15212341234", "王五");
return data;
}
// util方法
public void showKeyboard(View focusView) {
Object showing = focusView.getTag();
if (showing != null) {
return;
}
try {
InputMethodManager imm = (InputMethodManager) this
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(focusView, 0);
focusView.setTag(new Object());
} catch (Exception e) {
Log.e("SoftInput:Showing had a wrong.", e.toString());
}
}
public void hideKeyboard() {
View focusView = this.getCurrentFocus();
if (focusView == null || focusView.getTag() == null) {
return;
}
try {
InputMethodManager imm = ((InputMethodManager) this
.getSystemService(Activity.INPUT_METHOD_SERVICE));
imm.hideSoftInputFromWindow(focusView.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
focusView.setTag(null);
} catch (Exception e) {
Log.e("SoftInput:Hiding had a wrong.", e.toString());
}
}
public boolean isBlank(String str){
if(str == null || str.length() <= 0){
return true;
}
return false;
}
} activity_main.xml:
此外,為了防止在進入頁面的時候自動彈出軟鍵盤,可以在manifest的activity元素添加
源碼:http://download.csdn.net/download/goldenfish1919/6941249
Android Studio如何更改SDK的版本(針對非gradle)
最近事情太多了,也有一小段時間沒更新了,本來原來還有個寫哪些的計劃的,也打亂了,我就想到什麼寫什麼吧。 最近很多人在問Android Studio如何更改SDK版本,這邊
Android實現網絡加載時的對話框功能
效果預覽簡要說明現在android程序網絡請求操作是必不可少的,然而擁有好的交互體驗的程序對網絡耗時操作的處理尤為重要。代碼說明:dialog_loading.xml&l
Android 二維碼 生成和識別二維碼 附源碼下載
今天講一下目前移動領域很常用的技術——二維碼。現在大街小巷、各大網站都有二維碼的蹤跡,不管是IOS、Android、WP都有相關支持的軟件。之前我就想了解二維碼是如何工作
Android二維碼ZXING3.0(201403發布)接入
ZXING開源項目官方網站https://github.com/zxing/zxing/tree/zxing-3.0.0。 架包下載地址http://repo1.mave