我正在製作一個購物車應用程序,可以在添加項目時動態生成行。對於每個料品行,EditText字段用於料品數量,以便可以修改數量。由於數量需要爲整數進行計算,因此我使用parseInt來轉換從更改後的EditText中抓取的文本,並在輸入錯誤時將任何NFE刪除。如何停止焦點在ENTER上的EditText字段之間移動
當輸入是好的,一切工作正常。當輸入錯誤時,EditText被設置回到先前的值(根據需要),但是如果在它下面有另一個(動態生成的)行,則焦點切換到下一行中的EditText。期望的行爲是讓焦點保留在用戶想要更改的EditText中。
關於將重點放在成功更改上 - 虛擬鍵盤關閉成功,沒有任何事物保持關注。在那個try/catch塊中,我嘗試隱藏鍵盤,但這並沒有幫助...它在轉移到較低區域時保持打開狀態。
下面是一個形象,如果它有助於形象化: before and after hitting ENTER
我讀過其他職位有關使用requestFocus()方法,我在這裏使用它,但它似乎並沒有產生任何影響 - 也許由於所有這些都是即時生成的?我還看到一些帖子說動態生成的視圖沒有任何可以抓住的ID來識別應該關注什麼,但是在這種情況下我可能沒有理解它。
那麼,在處理NFE並重置該字段的值之後,如何將焦點保留在用戶想要編輯的字段中?
下面是捕捉任何NFE具體代碼:
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
quantityCell.setText("" + savedQuantity);
quantityCell.requestFocus();
return false;
}
...這裏是所有進入產生對蒼蠅的EditText字段代碼:
// create quantity edittext and add to row
final EditText quantityView = new EditText(this);
quantityView.setLayoutParams(cellParams);
quantityView.setSingleLine();
quantityView.setPadding(5, 5, 5, 5);
quantityView.setText("" + theQuantity);
quantityView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// capture old value of quantity before changing it
EditText et = (EditText)v;
savedQuantity = Integer.parseInt(et.getText().toString());
return false;
}
});
quantityView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if (keyCode == KeyEvent.KEYCODE_ENTER) {
int quantity;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TableRow theRow = (TableRow) v.getParent();
TextView nameCell = (TextView) theRow.getChildAt(0);
String name = nameCell.getText().toString();
EditText quantityCell = (EditText) theRow.getChildAt(1);
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
quantityCell.setText("" + savedQuantity);
quantityCell.requestFocus();
return false;
}
TextView unitCell = (TextView) theRow.getChildAt(2);
double unit = Double.parseDouble(unitCell.getText().toString().substring(1));
TextView totalCell = (TextView) theRow.getChildAt(3);
double total = Double.parseDouble(totalCell.getText().toString().substring(1));
totalPrice -= total;
totalQuantity -= quantity;
cartDB.changeQuantity(name, quantity, unit);
removeAllRows();
writeOrderTable();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
return true;
}
return false;
}
});
// set length of edittext line
productRow.addView(quantityView);
編輯: 看看那個catch子句中的代碼,我猜想隱藏虛擬鍵盤的行不會太多,如果所需的字段首先保留了任何焦點,那麼也許我應該刪除它。它存在的原因是我試圖做到這一點(隱藏虛擬鍵盤),只是爲了消除任何焦點,而且這種方法無效。下面的領域仍然抓住焦點,鍵盤仍然打開。
另一編輯: 物理鍵盤不會發生這種情況 - 至少在通過計算機鍵盤使用Genymotion虛擬設備時(不能使用內置AVD,我有AMD cpu)。當同一個模擬器設置爲使用虛擬鍵盤時,會出現問題。
FINAL EDIT: 我改變了try/catch塊,並且它按照需要工作。變化是catch子句中:
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
quantity = savedQuantity;
}
某些代碼後在更大的塊上方捲起處理重置字段當用戶輸入錯誤的數據。我猜測發生了什麼事的原因是我試圖用舊代碼中的setText()方法恢復舊值。
翻譯該網頁,從我可以在文檔中看到了有關使用的onkeydown陷阱是,它不是後虛擬鍵盤不可靠,並且大多數不會實現它來捕捉「ENTER」。 這是所有正在生成沒有該屬性的XML,但它是一個好主意。我添加了這一行: quantityView.setInputType(InputType.TYPE_CLASS_NUMBER); 它確實限制了用戶輸入數字,但仍然可以提交一個空值並且焦點仍然移動...所以幾乎是一個解決方案。 – raboyle
要將此標記爲已回答...發現感謝您的帖子發生了什麼,@VoidExplorer – raboyle
歡迎您&愉快編碼:) – VoidExplorer