Я включу мои активность_основной.xml и мои файлы MainActivity.java ниже.Я просматриваю все коды, которые мне возвращают, и не могу понять, почему мой эмулятор запустится, но я не получаю ответа на нажатия кнопок или ввод данных пользователем.Это простой калькулятор чаевых, который я строю на Android Studio, и я довольно новичок, но я действительно думаю, что, возможно, неправильно поместил имя экземпляра или переменной где-то, что отбрасывает меня.Чтобы прояснить мой вопрос, я не понимаю, что если код компилируется в эмулятор, который запускает, почему ни одна из моих пользовательских данных не будет вычисляться при нажатии кнопки.Мне также нужно добавить кнопку обновления, если у кого-то есть предложения очистить все поля после завершения работы пользователя.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Row 1: Text label placed in column zero,
text field placed in column two and allowed to span two columns. So a total of 4 columns in this row -->
<TableRow>
<TextView
android:id="@+id/txtLbl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl1"/>
<EditText
android:id="@+id/txtAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:layout_column="1"
android:layout_span="3"
/>
</TableRow>
<!-- Row 2: Text label placed in column zero,
text field placed in column two and (post-book publication)
surrounded
by increment and decrement buttons. So a total of 4 columns in
this row -->
<TableRow>
<TextView
android:id="@+id/txtLbl2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:onClick="decrement"/>
<EditText
android:id="@+id/txtPeople"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numeric="integer"
android:text="2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:onClick="increment"/>
</TableRow>
<TableRow>
<TextView
android:id="@+id/txtLbl3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textLbl3"/>
</TableRow>
<!-- Row 4: RadioGroup for RadioButtons placed at column zero
with a column span of three, thus creating one radio button
per cell of the table row. Last cell number 4 has the
text field to enter a custom tip percentage -->
<TableRow>
<RadioGroup
android:id="@+id/RadioGroupTips"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_span="3"
android:checkedButton="@+id/radioFifteen">
<RadioButton android:id="@+id/radioFifteen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxt15"
android:textSize="15sp" />
<RadioButton android:id="@+id/radioTwenty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxt20"
android:textSize="15sp" />
<RadioButton android:id="@+id/radioOther"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxtOther"
android:textSize="15sp" />
</RadioGroup>
<EditText
android:id="@+id/txtTipOther"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="decimal"/>
</TableRow>
<!-- Row for the Calculate and Rest buttons. The Calculate button
is placed at column two, and Reset at column three -->
<TableRow>
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:text="@string/btnReset"/>
<Button
android:id="@+id/btnCalculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:text="@string/btnCalculate"/>
</TableRow>
<!-- TableLayout allows any other views to be inserted between
the TableRow elements. So inserting a blank view to create a
line separator. This separator view is used to separate
the area below the buttons which will display the
calculation results -->
<View
android:layout_height="2px"
android:background="#DDFFDD"
android:layout_marginTop="5dip"
android:layout_marginBottom="5dip"/>
<!-- Again table row is used to place the result textviews
at column zero and the result in textviews at column two -->
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl4"/>
<TextView
android:id="@+id/txtTipAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl5"/>
<TextView
android:id="@+id/txtTotalToPay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl6"/>
<TextView
android:id="@+id/txtTipPerPerson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
</TableLayout>
MainActivity.java
package com.examples.tipcalc;
import java.text.NumberFormat;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
public class TipsterActivity {
final static int DEFAULT_NUM_PEOPLE = 3;
final static NumberFormat formatter =
NumberFormat.getCurrencyInstance();
// Widgets in the application
private EditText txtAmount;
private EditText txtPeople;
private EditText txtTipOther;
private RadioGroup rdoGroupTips;
private Button btnCalculate;
private Button btnReset;
private TextView txtTipAmount;
private TextView txtTotalToPay;
private TextView txtTipPerPerson;
// For the id of radio button selected
private int radioCheckedId = -1;
private NumberPickerLogic mLogic;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Access the various widgets by their id in R.java
txtAmount = (EditText) findViewById(R.id.txtAmount);
//On app load, the cursor should be in the Amount field
txtAmount.requestFocus();
txtPeople = (EditText) findViewById(R.id.txtPeople);
txtPeople.setText(Integer.toString(DEFAULT_NUM_PEOPLE));
txtTipOther = (EditText) findViewById(R.id.txtTipOther);
rdoGroupTips = (RadioGroup) findViewById(R.id.RadioGroupTips);
btnCalculate = (Button) findViewById(R.id.btnCalculate);
//On app load, the Calculate button is disabled
btnCalculate.setEnabled(false);
btnReset = (Button) findViewById(R.id.btnReset);
txtTipAmount = (TextView) findViewById(R.id.txtTipAmount);
txtTotalToPay = (TextView) findViewById(R.id.txtTotalToPay);
txtTipPerPerson = (TextView) findViewById(R.id.txtTipPerPerson);
// On app load, disable the 'Other tip' percentage text field
txtTipOther.setEnabled(false);
/*
* Attach a OnCheckedChangeListener to the
* radio group to monitor radio buttons selected by user
*/
rdoGroupTips.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// Enable/disable Other Percentage tip field
if (checkedId == R.id.radioFifteen
|| checkedId == R.id.radioTwenty) {
txtTipOther.setEnabled(false);
/*
* Enable the calculate button if Total Amount and No. of
* People fields have valid values.
*/
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0);
}
if (checkedId == R.id.radioOther) {
// enable the Other Percentage tip field
txtTipOther.setEnabled(true);
// set the focus to this field
txtTipOther.requestFocus();
/*
* Enable the calculate button if Total Amount and No. of
* People fields have valid values. Also ensure that user
* has entered a Other Tip Percentage value before enabling
* the Calculate button.
*/
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0);
}
// To determine the tip percentage choice made by user
radioCheckedId = checkedId;
}
});
/*
* Attach a KeyListener to the Tip Amount, No. of People and Other Tip
* Percentage text fields
*/
txtAmount.setOnKeyListener(mKeyListener);
txtPeople.setOnKeyListener(mKeyListener);
txtTipOther.setOnKeyListener(mKeyListener);
btnCalculate.setOnClickListener(mClickListener);
btnReset.setOnClickListener(mClickListener);
/** Create a NumberPickerLogic to handle the + and - keys */
mLogic = new NumberPickerLogic(txtPeople, 1, Integer.MAX_VALUE);
}
/*
* KeyListener for the Total Amount, No of People and Other Tip Percentage
* fields. We need to apply this key listener to check for following
* conditions:
*
* 1) If user selects Other tip percentages, then the other tip text field
* should have a valid tip percentage entered by the user. Enable the
* Calculate button only when user enters a valid value.
*
* 2) If user does not enter values in the Total Amount and No of People,
* we cannot perform the calculations. Hence enable the Calculate button
* only when user enters a valid values.
*/
private OnKeyListener mKeyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (v.getId()) {
case R.id.txtAmount:
case R.id.txtPeople:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0);
break;
case R.id.txtTipOther:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0);
break;
}
return false;
}
};
/**
* ClickListener for the Calculate and Reset buttons.
* Depending on the button clicked, the corresponding
* method is called.
*/
private OnClickListener mClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.btnCalculate) {
calculate();
} else reset();
}
};
/**
* Resets the results text views at the bottom of the screen as well as
* resets the text fields and radio buttons.
*/
private void reset() {
txtTipAmount.setText("");
txtTotalToPay.setText("");
txtTipPerPerson.setText("");
txtAmount.setText("");
txtPeople.setText(Integer.toString(DEFAULT_NUM_PEOPLE));
txtTipOther.setText("");
rdoGroupTips.clearCheck();
rdoGroupTips.check(R.id.radioFifteen);
// set focus on the first field
txtAmount.requestFocus();
}
public void decrement(View v) {
mLogic.decrement();
}
public void increment(View v) {
mLogic.increment();
}
/**
* Calculate the tip as per data entered by the user.
*/
private void calculate() {
Double billAmount = Double.parseDouble(
txtAmount.getText().toString());
Double totalPeople = Double.parseDouble(
txtPeople.getText().toString());
Double percentage = null;
boolean isError = false;
if (billAmount < 1.0) {
showErrorAlert("Enter a valid Total Amount.",
txtAmount.getId());
isError = true;
}
if (totalPeople < 1.0) {
showErrorAlert("Enter a valid number of people.",
txtPeople.getId());
isError = true;
}
/*
* If user never changes radio selection, then it means
* the default selection of 15% is in effect. But it's
* safer to verify...
*/
if (radioCheckedId == -1) {
radioCheckedId = rdoGroupTips.getCheckedRadioButtonId();
}
if (radioCheckedId == R.id.radioFifteen) {
percentage = 15.00;
} else if (radioCheckedId == R.id.radioTwenty) {
percentage = 20.00;
} else if (radioCheckedId == R.id.radioOther) {
percentage = Double.parseDouble(
txtTipOther.getText().toString());
if (percentage < 1.0) {
showErrorAlert("Enter a valid Tip percentage",
txtTipOther.getId());
isError = true;
}
}
/*
* If all fields are populated with valid values, then proceed to
* calculate the tips
*/
if (!isError) {
double tipAmount = ((billAmount * percentage) / 100);
double totalToPay = billAmount + tipAmount;
double perPersonPays = totalToPay / totalPeople;
txtTipAmount.setText(formatter.format(tipAmount));
txtTotalToPay.setText(formatter.format(totalToPay));
txtTipPerPerson.setText(formatter.format(perPersonPays));
}
}
/**
* Shows the error message in an alert dialog
*
* @param errorMessage
* String the error message to show
* @param fieldId
* the Id of the field which caused the error.
* This is required so that the focus can be
* set on that field once the dialog is
* dismissed.
*/
private void showErrorAlert(String errorMessage, final int fieldId) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage(errorMessage)
.setNeutralButton("Close",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
findViewById(fieldId).requestFocus();
}
}).show();
}
private class NumberPickerLogic {
public NumberPickerLogic(EditText txtPeople, int i, int maxValue) {
}
}
}