自定義數字鍵盤 (NumberPad) 時,每次點擊按鈕直接 setText 會覆蓋原有內容。核心解決:用成員變量累積輸入字符串,點擊時 追加 而非替換。
// ❌ 錯誤:每次點擊都替換全文
one.setOnClickListener(v -> {
singleValue.setText("1"); // 只顯示 "1"
});
two.setOnClickListener(v -> {
singleValue.setText("2"); // 只顯示 "2","1" 丟失
});
public class NumberPadActivity extends AppCompatActivity {
private StringBuilder inputBuffer = new StringBuilder(); // 成員變量保存狀態
private TextView display;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_number_pad);
display = findViewById(R.id.priceInput);
// 統一設置點擊監聽
int[] btnIds = {R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4,
R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9};
for (int id : btnIds) {
findViewById(id).setOnClickListener(this::onNumberClick);
}
findViewById(R.id.btnClear).setOnClickListener(v -> clearInput());
findViewById(R.id.btnDelete).setOnClickListener(v -> deleteLast());
}
private void onNumberClick(View v) {
Button btn = (Button) v;
String digit = btn.getText().toString();
inputBuffer.append(digit); // 追加
display.setText(inputBuffer.toString());
}
private void clearInput() {
inputBuffer.setLength(0);
display.setText("");
}
private void deleteLast() {
if (inputBuffer.length() > 0) {
inputBuffer.deleteCharAt(inputBuffer.length() - 1);
display.setText(inputBuffer.toString());
}
}
}
public class NumberPadView extends LinearLayout {
private StringBuilder buffer = new StringBuilder();
private TextView display;
private OnInputChangeListener listener;
public interface OnInputChangeListener {
void onInputChanged(String currentInput);
void onConfirm(String finalInput);
}
public NumberPadView(Context context, AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.view_number_pad, this);
display = findViewById(R.id.display);
setupButtons();
}
private void setupButtons() {
int[] ids = {R.id.n0,R.id.n1,R.id.n2,R.id.n3,R.id.n4,R.id.n5,R.id.n6,R.id.n7,R.id.n8,R.id.n9};
for (int id : ids) findViewById(id).setOnClickListener(v -> append(((Button)v).getText().toString()));
findViewById(R.id.clear).setOnClickListener(v -> clear());
findViewById(R.id.delete).setOnClickListener(v -> deleteLast());
findViewById(R.id.confirm).setOnClickListener(v -> {
if (listener != null) listener.onConfirm(buffer.toString());
});
}
private void append(String digit) {
buffer.append(digit);
updateDisplay();
}
private void clear() { buffer.setLength(0); updateDisplay(); }
private void deleteLast() { if (buffer.length()>0) buffer.deleteCharAt(buffer.length()-1); updateDisplay(); }
private void updateDisplay() { display.setText(buffer); if (listener!=null) listener.onInputChanged(buffer.toString()); }
public void setOnInputChangeListener(OnInputChangeListener l) { this.listener = l; }
public String getInput() { return buffer.toString(); }
}
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/display" android:layout_width="match_parent"
android:layout_height="60dp" android:gravity="center|end" android:textSize="24sp"
android:padding="16dp" android:background="#f0f0f0"/>
<GridLayout android:columnCount="3" android:rowCount="4" ...>
<Button android:id="@+id/n1" android:text="1" style="@style/NumberPadButton"/>
<Button android:id="@+id/n2" android:text="2" style="@style/NumberPadButton"/>
<Button android:id="@+id/n3" android:text="3" style="@style/NumberPadButton"/>
<Button android:id="@+id/n4" android:text="4" style="@style/NumberPadButton"/>
<Button android:id="@+id/n5" android:text="5" style="@style/NumberPadButton"/>
<Button android:id="@+id/n6" android:text="6" style="@style/NumberPadButton"/>
<Button android:id="@+id/n7" android:text="7" style="@style/NumberPadButton"/>
<Button android:id="@+id/n8" android:text="8" style="@style/NumberPadButton"/>
<Button android:id="@+id/n9" android:text="9" style="@style/NumberPadButton"/>
<Button android:id="@+id/clear" android:text="C" style="@style/NumberPadButton.Action"/>
<Button android:id="@+id/n0" android:text="0" style="@style/NumberPadButton"/>
<Button android:id="@+id/delete" android:text="<-" style="@style/NumberPadButton.Action"/>
<Button android:id="@+id/confirm" android:text="確定" style="@style/NumberPadButton.Primary"/>
</GridLayout>
</LinearLayout>
buffer.append() 而非 setText(new)。這是「狀態管理」最基礎的實踐:UI 只負責渲染狀態,事件只負責修改狀態。