Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Use an EditTextPreference element In this exercise, you’ll modify the Tip Calcul

ID: 3591767 • Letter: U

Question

Use an EditTextPreference element

In this exercise, you’ll modify the Tip Calculator app presented in this chapter so it uses an

EditTextPreference element. Although this type of preference wasn’t described in this

chapter, it works similarly to the CheckBoxPreference element, and you can look it up in

the documentation for the API if necessary.

When you’re done, a test run should look like this:

1. Open the preferences.xml file in the xml directory. Add an EditTextPreference element

for a setting named Name. This setting should allow the user to enter his or her full

name.

2. Run the app and use the Settings activity to enter your name.

3. Open the layout of the activity. Modify the layout, so it includes a fifth row that can

display a name.

Open the class for the Tip Calculator activity. Modify this code so it gets the name

from the preferences and displays that name in

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
       
android:key="pref_remember_percent"
       
android:title="@string/remember_percent_title"
       
android:summary="@string/remember_percent_summary"
       
android:defaultValue="true" />
    <ListPreference
       
android:key="pref_rounding"
       
android:title="@string/rounding_title"
       
android:summary="@string/rounding_summary"
       
android:dialogTitle="@string/rounding_title"
       
android:entries="@array/rounding_keys"
       
android:entryValues="@array/rounding_values"
       
android:defaultValue="@string/rounding_default" />   
</PreferenceScreen>

SettingsActivity

package com.murach.tipcalculator;

import android.app.Activity;
import android.os.Bundle;

public class SettingsActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        // Display the fragment as the main content.
       
getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
    }
}

activity_about.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context=".AboutActivity" >

    <TextView
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:padding="10dp"
       
android:text="@string/about" />

</RelativeLayout>

activity_tip_calculator.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:padding="10dp" >

    <!-- The bill amount -->

   
<TextView
       
android:id="@+id/billAmountLabel"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:padding="10dp"
       
android:text="@string/bill_amount_label"
       
android:textSize="20sp"
       
android:textStyle="bold" />

    <EditText
       
android:id="@+id/billAmountEditText"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignBaseline="@+id/billAmountLabel"
        
android:layout_marginLeft="5dp"
       
android:layout_toRightOf="@+id/billAmountLabel"
       
android:ems="8"
       
android:inputType="numberDecimal"
       
android:text="@string/bill_amount"
       
android:textSize="20sp" >

        <requestFocus />
    </EditText>

    <!-- The tip percent -->
   
   
<TextView
       
android:id="@+id/percentLabel"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignLeft="@+id/billAmountLabel"
      
android:layout_below="@+id/billAmountLabel"
       
android:padding="10dp"
       
android:text="@string/tip_percent_label"
       
android:textSize="20sp"
       
android:textStyle="bold" />

    <TextView
       
android:id="@+id/percentTextView"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignBaseline="@+id/percentLabel"
       
android:layout_alignLeft="@+id/billAmountEditText"
       
android:padding="5dp"
       
android:text="@string/tip_percent"
       
android:textSize="20sp" />

    <Button
       
android:id="@+id/percentDownButton"
       
android:layout_width="45dp"
       
android:layout_height="45dp"
       
android:layout_alignBaseline="@+id/percentTextView"
       
android:layout_marginLeft="25dp"
       
android:layout_toRightOf="@+id/percentTextView"
       
android:text="@string/decrease"
       
android:textSize="20sp" />

    <Button
       
android:id="@+id/percentUpButton"
       
android:layout_width="45dp"
        
android:layout_height="45dp"
       
android:layout_alignBaseline="@+id/percentDownButton"
       
android:layout_toRightOf="@+id/percentDownButton"
       
android:text="@string/increase"
       
android:textSize="20sp" />

    <!-- the tip amount -->
   
   
<TextView
       
android:id="@+id/tipLabel"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignLeft="@+id/percentLabel"
       
android:layout_below="@+id/percentLabel"
       
android:padding="10dp"
       
android:text="@string/tip_amount_label"
       
android:textSize="20sp"
       
android:textStyle="bold" />

    <TextView
       
android:id="@+id/tipTextView"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignBaseline="@+id/tipLabel"
       
android:layout_alignLeft="@id/billAmountEditText"
       
android:padding="5dp"
       
android:text="@string/tip_amount"
       
android:textSize="20sp" />

    <!-- the total -->
   
   
<TextView
       
android:id="@+id/totalLabel"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignLeft="@+id/tipLabel"
       
android:layout_below="@+id/tipLabel"
      
android:padding="10dp"
       
android:text="@string/total_amount_label"
       
android:textSize="20sp"
       
android:textStyle="bold" />

    <TextView
       
android:id="@+id/totalTextView"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_alignBaseline="@+id/totalLabel"
       
android:layout_alignLeft="@+id/tipTextView"
       
android:padding="5dp"
       
android:text="@string/total_amount"
       
android:textSize="20sp" />   

</RelativeLayout>

Java TipCalculatorActivity

package com.murach.tipcalculator;

import java.text.NumberFormat;

import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class TipCalculatorActivity extends Activity
implements OnEditorActionListener, OnClickListener {

    // define variables for the widgets
   
private EditText billAmountEditText;
    private TextView percentTextView;  
    private Button   percentUpButton;
    private Button   percentDownButton;
    private TextView tipTextView;
    private TextView totalTextView;
   
    // define instance variables that should be saved
   
private String billAmountString = "";
    private float tipPercent = .15f;
   
    // define rounding constants
   
private final int ROUND_NONE = 0;
    private final int ROUND_TIP = 1;
    private final int ROUND_TOTAL = 2;
   
    // set up preferences
   
private SharedPreferences prefs;
    private boolean rememberTipPercent = true;
    private int rounding = ROUND_NONE;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tip_calculator);
       
        // get references to the widgets
       
billAmountEditText = (EditText) findViewById(R.id.billAmountEditText);
        percentTextView = (TextView) findViewById(R.id.percentTextView);
        percentUpButton = (Button) findViewById(R.id.percentUpButton);
        percentDownButton = (Button) findViewById(R.id.percentDownButton);
        tipTextView = (TextView) findViewById(R.id.tipTextView);
        totalTextView = (TextView) findViewById(R.id.totalTextView);

        // set the listeners
       
billAmountEditText.setOnEditorActionListener(this);
        percentUpButton.setOnClickListener(this);
        percentDownButton.setOnClickListener(this);
       
        // set the default values for the preferences
       
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
       
        // get default SharedPreferences object
       
prefs = PreferenceManager.getDefaultSharedPreferences(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_tip_calculator, menu);
        return true;
    }
   
    @Override
    public void onPause() {
        // save the instance variables      
       
Editor editor = prefs.edit();       
        editor.putString("billAmountString", billAmountString);
        editor.putFloat("tipPercent", tipPercent);
        editor.commit();       

        super.onPause();     
    }
   
    @Override
    public void onResume() {
        super.onResume();
       
        // get preferences
       
rememberTipPercent = prefs.getBoolean("pref_remember_percent", true);
        rounding = Integer.parseInt(prefs.getString("pref_rounding", "0"));

        // get the instance variables
       
billAmountString = prefs.getString("billAmountString", "");
        if (rememberTipPercent) {
            tipPercent = prefs.getFloat("tipPercent", 0.15f);
        } else {
            tipPercent = 0.15f;
        }

        // set the bill amount on its widget
       
billAmountEditText.setText(billAmountString);
       
        // calculate and display
       
calculateAndDisplay();
    }
   
    public void calculateAndDisplay() {       
        // get the bill amount
       
billAmountString = billAmountEditText.getText().toString();
        float billAmount;
        if (billAmountString.equals("")) {
            billAmount = 0;
        }
        else {
            billAmount = Float.parseFloat(billAmountString);
        }
       
        // calculate tip and total
       
float tipAmount = 0;
        float totalAmount = 0;
        float tipPercentToDisplay = 0;
        if (rounding == ROUND_NONE) {
            tipAmount = billAmount * tipPercent;
            totalAmount = billAmount + tipAmount;
            tipPercentToDisplay = tipPercent;
        }
        else if (rounding == ROUND_TIP) {
            tipAmount = StrictMath.round(billAmount * tipPercent);
            totalAmount = billAmount + tipAmount;
            tipPercentToDisplay = tipAmount / billAmount;
        }
        else if (rounding == ROUND_TOTAL) {
            float tipNotRounded = billAmount * tipPercent;
            totalAmount = StrictMath.round(billAmount + tipNotRounded);
            tipAmount = totalAmount - billAmount;
            tipPercentToDisplay = tipAmount / billAmount;
        }
       
        // display the other results with formatting
       
NumberFormat currency = NumberFormat.getCurrencyInstance();
        tipTextView.setText(currency.format(tipAmount));
        totalTextView.setText(currency.format(totalAmount));
       
        NumberFormat percent = NumberFormat.getPercentInstance();
        percentTextView.setText(percent.format(tipPercentToDisplay));
    }
   
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        int keyCode = -1;
        if (event != null) {
           keyCode = event.getKeyCode();
        }
        if (actionId == EditorInfo.IME_ACTION_DONE ||
            actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
            keyCode == KeyEvent.KEYCODE_DPAD_CENTER ||
            keyCode == KeyEvent.KEYCODE_ENTER) {
            calculateAndDisplay();
        }       
        return false;
    }
   
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.percentDownButton:
            tipPercent = tipPercent - .01f;
            calculateAndDisplay();
            break;
        case R.id.percentUpButton:
            tipPercent = tipPercent + .01f;
            calculateAndDisplay();
            break;
        }
    }
   
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                // Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show();
                
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
                return true;
            case R.id.menu_about:
                // Toast.makeText(this, "About", Toast.LENGTH_SHORT).show();
               
startActivity(new Intent(getApplicationContext(), AboutActivity.class));
                return true;
           
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

5:26 3G Tip Calculator Bill Amount 94.60 Percent Tip Total Name 20% $18.92 $113.52 John Smith

Explanation / Answer


package com.murach.tipcalculator;

import android.app.Activity;
import android.os.Bundle;

public class SettingsActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}

activity_about.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AboutActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@string/about" />

</RelativeLayout>


activity_tip_calculator.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp" >

<!-- The bill amount -->

<TextView
android:id="@+id/billAmountLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@string/bill_amount_label"
android:textSize="20sp"
android:textStyle="bold" />

<EditText
android:id="@+id/billAmountEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/billAmountLabel"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@+id/billAmountLabel"
android:ems="8"
android:inputType="numberDecimal"
android:text="@string/bill_amount"
android:textSize="20sp" >

<requestFocus />
</EditText>

<!-- The tip percent -->

<TextView
android:id="@+id/percentLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/billAmountLabel"
android:layout_below="@+id/billAmountLabel"
android:padding="10dp"
android:text="@string/tip_percent_label"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:id="@+id/percentTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/percentLabel"
android:layout_alignLeft="@+id/billAmountEditText"
android:padding="5dp"
android:text="@string/tip_percent"
android:textSize="20sp" />

<Button
android:id="@+id/percentDownButton"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignBaseline="@+id/percentTextView"
android:layout_marginLeft="25dp"
android:layout_toRightOf="@+id/percentTextView"
android:text="@string/decrease"
android:textSize="20sp" />

<Button
android:id="@+id/percentUpButton"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignBaseline="@+id/percentDownButton"
android:layout_toRightOf="@+id/percentDownButton"
android:text="@string/increase"
android:textSize="20sp" />

<!-- the tip amount -->

<TextView
android:id="@+id/tipLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/percentLabel"
android:layout_below="@+id/percentLabel"
android:padding="10dp"
android:text="@string/tip_amount_label"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:id="@+id/tipTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tipLabel"
android:layout_alignLeft="@id/billAmountEditText"
android:padding="5dp"
android:text="@string/tip_amount"
android:textSize="20sp" />

<!-- the total -->

<TextView
android:id="@+id/totalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tipLabel"
android:layout_below="@+id/tipLabel"
android:padding="10dp"
android:text="@string/total_amount_label"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:id="@+id/totalTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/totalLabel"
android:layout_alignLeft="@+id/tipTextView"
android:padding="5dp"
android:text="@string/total_amount"
android:textSize="20sp" />

</RelativeLayout>
Java TipCalculatorActivity
package com.murach.tipcalculator;

import java.text.NumberFormat;

import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class TipCalculatorActivity extends Activity
implements OnEditorActionListener, OnClickListener {

// define variables for the widgets
private EditText billAmountEditText;
private TextView percentTextView;  
private Button percentUpButton;
private Button percentDownButton;
private TextView tipTextView;
private TextView totalTextView;

// define instance variables that should be saved
private String billAmountString = "";
private float tipPercent = .15f;

// define rounding constants
private final int ROUND_NONE = 0;
private final int ROUND_TIP = 1;
private final int ROUND_TOTAL = 2;

// set up preferences
private SharedPreferences prefs;
private boolean rememberTipPercent = true;
private int rounding = ROUND_NONE;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_calculator);

// get references to the widgets
billAmountEditText = (EditText) findViewById(R.id.billAmountEditText);
percentTextView = (TextView) findViewById(R.id.percentTextView);
percentUpButton = (Button) findViewById(R.id.percentUpButton);
percentDownButton = (Button) findViewById(R.id.percentDownButton);
tipTextView = (TextView) findViewById(R.id.tipTextView);
totalTextView = (TextView) findViewById(R.id.totalTextView);

// set the listeners
billAmountEditText.setOnEditorActionListener(this);
percentUpButton.setOnClickListener(this);
percentDownButton.setOnClickListener(this);

// set the default values for the preferences
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

// get default SharedPreferences object
prefs = PreferenceManager.getDefaultSharedPreferences(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_tip_calculator, menu);
return true;
}

@Override
public void onPause() {
// save the instance variables   
Editor editor = prefs.edit();
editor.putString("billAmountString", billAmountString);
editor.putFloat("tipPercent", tipPercent);
editor.commit();

super.onPause();
}

@Override
public void onResume() {
super.onResume();

// get preferences
rememberTipPercent = prefs.getBoolean("pref_remember_percent", true);
rounding = Integer.parseInt(prefs.getString("pref_rounding", "0"));

// get the instance variables
billAmountString = prefs.getString("billAmountString", "");
if (rememberTipPercent) {
tipPercent = prefs.getFloat("tipPercent", 0.15f);
} else {
tipPercent = 0.15f;
}

// set the bill amount on its widget
billAmountEditText.setText(billAmountString);

// calculate and display
calculateAndDisplay();
}

public void calculateAndDisplay() {
// get the bill amount
billAmountString = billAmountEditText.getText().toString();
float billAmount;
if (billAmountString.equals("")) {
billAmount = 0;
}
else {
billAmount = Float.parseFloat(billAmountString);
}

// calculate tip and total
float tipAmount = 0;
float totalAmount = 0;
float tipPercentToDisplay = 0;
if (rounding == ROUND_NONE) {
tipAmount = billAmount * tipPercent;
totalAmount = billAmount + tipAmount;
tipPercentToDisplay = tipPercent;
}
else if (rounding == ROUND_TIP) {
tipAmount = StrictMath.round(billAmount * tipPercent);
totalAmount = billAmount + tipAmount;
tipPercentToDisplay = tipAmount / billAmount;
}
else if (rounding == ROUND_TOTAL) {
float tipNotRounded = billAmount * tipPercent;
totalAmount = StrictMath.round(billAmount + tipNotRounded);
tipAmount = totalAmount - billAmount;
tipPercentToDisplay = tipAmount / billAmount;
}

// display the other results with formatting
NumberFormat currency = NumberFormat.getCurrencyInstance();
tipTextView.setText(currency.format(tipAmount));
totalTextView.setText(currency.format(totalAmount));

NumberFormat percent = NumberFormat.getPercentInstance();
percentTextView.setText(percent.format(tipPercentToDisplay));
}

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int keyCode = -1;
if (event != null) {
keyCode = event.getKeyCode();
}
if (actionId == EditorInfo.IME_ACTION_DONE ||
actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
keyCode == KeyEvent.KEYCODE_DPAD_CENTER ||
keyCode == KeyEvent.KEYCODE_ENTER) {
calculateAndDisplay();
}
return false;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.percentDownButton:
tipPercent = tipPercent - .01f;
calculateAndDisplay();
break;
case R.id.percentUpButton:
tipPercent = tipPercent + .01f;
calculateAndDisplay();
break;
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
// Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
return true;
case R.id.menu_about:
// Toast.makeText(this, "About", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), AboutActivity.class));
return true;

default:
return super.onOptionsItemSelected(item);
}
}
}