Совет по разработке приложения: неправильная маркировка экземпляра калькулятора - PullRequest
0 голосов
/ 01 октября 2018

Я включу мои активность_основной.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) {
    }
}
}
...