代码审核中的
每当我尝试运行我的Android应用时,它会显示标题栏,其下方没有任何内容。大约两分钟后,它崩溃了。这是logcat:
我知道问题源于我第一次尝试使用片段结构。这是我的代码:
/* My verion of the Deitel Tip Calculator */
package org.bh.tipcalculator2;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.NotificationManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TipCalculator extends Activity {
// constants used when saving/restoring state
private static final String BILL_TOTAL = "BILL_TOTAL";
private static final String CUSTOM_PERCENT = "CUSTOM_PERCENT";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_calculator);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tip_calculator, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
private double currentBillTotal; // Bill as entered by the user
private int currentCustomPercent; // Custom tip % as set by user
private EditText billEditText; // Bill input widget
private EditText tip10EditText; // 10% tip output
private EditText tip15EditText; // 15% tip output
private EditText tip20EditText; // 20% tip output
private EditText tipCustomEditText; // ##% tip output
private EditText total10EditText; // 10% total output
private EditText total15EditText; // 15% total output
private EditText total20EditText; // 20% total output
private EditText totalCustomEditText; // ##% total output
private TextView customTipTextView; // Custom tip % output
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState == null)
{
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
currentBillTotal = 0;
currentCustomPercent = 18;
}
else
{
currentBillTotal = savedInstanceState.getDouble(BILL_TOTAL);
currentCustomPercent = savedInstanceState.getInt(CUSTOM_PERCENT);
}
View rootView = inflater.inflate(R.layout.fragment_tip_calculator, container, false);
tip10EditText = (EditText) rootView.findViewById(R.id.tip10EditText);
tip15EditText = (EditText) rootView.findViewById(R.id.tip15EditText);
tip20EditText = (EditText) rootView.findViewById(R.id.tip20EditText);
tipCustomEditText = (EditText) rootView.findViewById(R.id.tipCustomEditText);
total10EditText = (EditText) rootView.findViewById(R.id.total10EditText);
total15EditText = (EditText) rootView.findViewById(R.id.total15EditText);
total20EditText = (EditText) rootView.findViewById(R.id.total20EditText);
totalCustomEditText = (EditText) rootView.findViewById(R.id.totalCustomEditText);
customTipTextView = (TextView) rootView.findViewById(R.id.customTipTextView);
billEditText = (EditText) rootView.findViewById(R.id.billEditText);
//System.out.print(billEditText);
billEditText.addTextChangedListener(billEditTextWatcher);
SeekBar customSeekBar = (SeekBar) rootView.findViewById(R.id.customSeekBar);
customSeekBar.setOnSeekBarChangeListener(customSeekBarListener);
return rootView;
}
/**
* Calls {@link #updateStandard()} and then {@link #updateCustom()}.
*
* @see #updateStandard()
* @see #updateCustom()
*/
public void updateAll()
{
updateStandard();
updateCustom();
}
public void updateStandard()
{
calculateTipAndTotal(tip10EditText, total10EditText, .1);
calculateTipAndTotal(tip15EditText, total15EditText, .15);
calculateTipAndTotal(tip20EditText, total20EditText, .2);
}
public void updateCustom()
{
customTipTextView.setText(currentCustomPercent + "%");
calculateTipAndTotal(tipCustomEditText, totalCustomEditText, currentCustomPercent);
}
public void calculateTipAndTotal(EditText tipEditText, EditText totalEditText, double tip)
{
tipEditText .setText(String.format("%.02f", currentBillTotal * tip));
totalEditText.setText(String.format("%.02f", currentBillTotal * (tip + 1)));
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putDouble(BILL_TOTAL, currentBillTotal);
outState.putInt(CUSTOM_PERCENT, currentCustomPercent);
}
private SeekBar.OnSeekBarChangeListener customSeekBarListener =
new SeekBar.OnSeekBarChangeListener()
{
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
currentCustomPercent = seekBar.getProgress();
updateCustom();
}
@Override public void onStartTrackingTouch(SeekBar seekBar){}
@Override public void onStopTrackingTouch(SeekBar seekBar){}
}
;
private TextWatcher billEditTextWatcher =
new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try
{
currentBillTotal = extractDouble(s);
}
catch (NumberFormatException ex) // if we still didn't get a number
{
currentBillTotal = 0;
}
updateAll();
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after){}
@Override public void afterTextChanged(Editable editable){}
}
;
/**
* Attempts to extract the first double found. This ideally works with percents, currency
* notation, and other formats where the double is surrounded by delimiters and text, but is
* not interrupted by it.<br/>
*<br/>
* A double may look like any one of these, where {@code #} represents any number of digits 0
* through 9:
*
* <ul>
* <li>{@code #}</li>
* <li>{@code .#}</li>
* <li>{@code #.#}</li>
* </ul>
*
* @param possibleDouble a character sequence that might contain a double
*
* @return the extracted double
*
* @throws java.lang.NumberFormatException if a double could not be found
*/
public static double extractDouble(CharSequence possibleDouble)
{
/**
* Matches at least one digit, optionally preceded by a radix point, optionally preceded by
* any number of digits
*/
Matcher matcher = Pattern.compile("([0-9]*\\.)?[0-9]+").matcher(possibleDouble);
matcher.find();
return Double.parseDouble(matcher.group());
}
}
}
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TipCalculator"
tools:ignore="MergeRootFrame" >
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="org.bh.tipcalculator2.TipCalculator$PlaceholderFragment"
android:id="@+id/fragmentTipCalculator"
android:layout_gravity="center"
tools:layout="@layout/fragment_tip_calculator" />
</FrameLayout>
<TableLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".TipCalculator$PlaceholderFragment"
android:id="@+id/tableLayout"
android:stretchColumns="@string/tableLayoutStretchColumns">
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow0"
android:gravity="center_vertical|right">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/billTotalLabel"
android:id="@+id/billTextView"
android:textColor="@android:color/secondary_text_dark" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/billEditText"
android:inputType="numberDecimal"
android:layout_span="3"
android:text="@string/zeroCurrency"
android:selectAllOnFocus="false"
android:focusable="true"
android:focusableInTouchMode="true"
android:editable="true"
android:textIsSelectable="false"
android:textColor="@android:color/primary_text_dark"
android:hint="@string/billTotalHint"
android:enabled="true" />
<!--NumberPicker
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/billNumberPicker"
android:layout_span="3" /-->
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow2" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tipTextLabel"
android:id="@+id/tipLabelTextView"
android:gravity="center_vertical|right"
android:textColor="@android:color/secondary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/tip10EditText"
android:layout_weight="0"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark"
android:text="@string/zeroCurrency" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/tip15EditText"
android:layout_weight="0"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark"
android:text="@string/zeroCurrency" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/tip20EditText"
android:layout_weight="0"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark"
android:text="@string/zeroCurrency" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tenPercent"
android:id="@+id/tenTextView"
android:layout_column="1"
android:gravity="center_horizontal|bottom"
android:textColor="@android:color/secondary_text_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fifteenPercent"
android:id="@+id/fifteenTextView"
android:gravity="center_horizontal|bottom"
android:textColor="@android:color/secondary_text_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/twentyPercent"
android:id="@+id/twentyTextView2"
android:gravity="center_horizontal|bottom"
android:textColor="@android:color/secondary_text_dark" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow3" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/totalTextLabel"
android:id="@+id/textView"
android:gravity="center_vertical|right"
android:textColor="@android:color/secondary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/total10EditText"
android:layout_weight="0"
android:text="@string/zeroCurrency"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/total15EditText"
android:layout_weight="0"
android:text="@string/zeroCurrency"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/total20EditText"
android:layout_weight="0"
android:text="@string/zeroCurrency"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/spacerTableRow"
android:layout_weight="1">
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow4"
android:layout_gravity="bottom">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/customTextLabel"
android:id="@+id/customTextView"
android:gravity="center_vertical|right"
android:textColor="@android:color/secondary_text_dark" />
<SeekBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/customSeekBar"
android:indeterminate="false"
android:indeterminateOnly="false"
android:layout_span="2"
android:max="200"
android:progress="18" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/customTipReadoutPlaceholder"
android:id="@+id/customTipTextView"
android:gravity="center_vertical|left" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/tableRow5"
android:layout_gravity="bottom">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/tipTextLabel"
android:id="@+id/tipCustomTextView"
android:gravity="center_vertical|right"
android:textColor="@android:color/secondary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/tipCustomEditText"
android:layout_weight="0"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark"
android:text="@string/zeroCurrency" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/totalTextLabel"
android:id="@+id/totalCustomTextView"
android:gravity="center_vertical|right"
android:textColor="@android:color/secondary_text_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:id="@+id/totalCustomEditText"
android:layout_weight="0"
android:text="@string/zeroCurrency"
android:focusable="@bool/outputEditable"
android:enabled="@bool/outputEditable"
android:editable="@bool/outputEditable"
android:longClickable="@bool/outputEditable"
android:focusableInTouchMode="@bool/outputEditable"
android:clickable="@bool/outputEditable"
android:textColor="@android:color/primary_text_dark" />
</TableRow>
</TableLayout>
答案 0 :(得分:3)
问题出在这里:
public static class PlaceholderFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState == null)
{
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
currentBillTotal = 0;
currentCustomPercent = 18;
}
当您为PlaceholderFragment
创建视图时,您实际上正在创建另一个 PlaceholderFragment
并添加它。这将继续运行和消耗内存,直到它完全耗尽(并崩溃)。
简而言之,您应该删除该部分。该片段已被添加。