ExaltedDice.java

i have implemented methods from NumberPicker.java from the android source so i can use their method of filtering out anything that is not a number.

i have incremented the version / build number
from b11 to b12
This commit is contained in:
2010-09-21 16:00:33 +00:00
parent a6dc0e9082
commit 890f1f04ff
5 changed files with 225 additions and 187 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.TwentyCode.android.ExaltedDice" package="com.TwentyCode.android.ExaltedDice"
android:versionCode="11" android:versionName="1.0.0"> android:versionName="1.0.0" android:versionCode="12">
<application android:icon="@drawable/icon" android:label="@string/app_name"> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ExaltedDice" <activity android:name=".ExaltedDice"

View File

@@ -10,40 +10,50 @@ import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Vibrator; import android.os.Vibrator;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.method.NumberKeyListener;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnLongClickListener; import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class ExaltedDice extends Activity implements OnClickListener, OnLongClickListener, OnItemClickListener { public class ExaltedDice extends Activity implements OnClickListener, OnLongClickListener, OnItemClickListener, OnFocusChangeListener {
private TextView dice; private EditText dice;
private ListView listview; private ListView listview;
private ArrayList<String> rollHistory = new ArrayList<String>(); private ArrayList<String> rollHistory = new ArrayList<String>();
private ArrayList<Integer> rolled = new ArrayList<Integer>(); private ArrayList<Integer> rolled = new ArrayList<Integer>();
private int intSuccesses; private int intSuccesses;
private int mCurrent; private int mCurrent;
private static boolean mIncrement; private static boolean mIncrement;
private static boolean mDecrement; private static boolean mDecrement;
private InputFilter mNumberInputFilter;
private String[] mDisplayedValues;
protected int mPrevious;
private Formatter mFormatter;
//the speed in milliseconds for dice increment or decrement //the speed in milliseconds for dice increment or decrement
private long mSpeed = 300; private long mSpeed = 300;
//the least and most dice allowed //the least and most dice allowed
private int mStart = 1; private int mStart = 1;
private int mEnd = 999; private int mEnd = 999;
private static final int MENU_QUIT = Menu.FIRST;
private static final int MENU_CLEAR = Menu.FIRST + 1;
protected PostMortemReportExceptionHandler mDamageReport = new PostMortemReportExceptionHandler(this);
private static final String TAG = "ExaltedDice";
private Handler mHandler; private Handler mHandler;
//this runnable will be used to increment or decrement the amount of dice being rolled //this runnable will be used to increment or decrement the amount of dice being rolled
@@ -59,159 +69,106 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
} }
}; };
private static final String TAG = "ExaltedDice"; private static final char[] DIGIT_CHARACTERS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
};
public interface Formatter {
String toString(int value);
}
private class NumberPickerInputFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (mDisplayedValues == null) {
return mNumberInputFilter.filter(source, start, end, dest, dstart, dend);
}
CharSequence filtered = String.valueOf(source.subSequence(start, end));
String result = String.valueOf(dest.subSequence(0, dstart))
+ filtered
+ dest.subSequence(dend, dest.length());
String str = String.valueOf(result).toLowerCase();
for (String val : mDisplayedValues) {
val = val.toLowerCase();
if (val.startsWith(str)) {
return filtered;
}
}
return "";
}
}
private class NumberRangeKeyListener extends NumberKeyListener {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
CharSequence filtered = super.filter(source, start, end, dest, dstart, dend);
if (filtered == null) {
filtered = source.subSequence(start, end);
}
String result = String.valueOf(dest.subSequence(0, dstart))
+ filtered
+ dest.subSequence(dend, dest.length());
if ("".equals(result)) {
return result;
}
int val = getSelectedPos(result);
/* Ensure the user can't type in a value greater
* than the max allowed. We have to allow less than min
* as the user might want to delete some numbers
* and then type a new number.
*/
if (val > mEnd) {
return "";
} else {
return filtered;
}
}
@Override
protected char[] getAcceptedChars() {
return DIGIT_CHARACTERS;
}
// XXX This doesn't allow for range limits when controlled by a
// soft input method!
public int getInputType() {
return InputType.TYPE_CLASS_NUMBER;
}
}
/** /**
* menu options * stops decrementing of dice after longpress
*/
private static final int MENU_QUIT = Menu.FIRST;
private static final int MENU_CLEAR = Menu.FIRST + 1;
protected PostMortemReportExceptionHandler mDamageReport = new PostMortemReportExceptionHandler(this);
protected void changeCurrent(int current) {
// Wrap around the values if we go past the start or end
if (current > mEnd) {
current = mStart;
} else if (current < mStart) {
current = mEnd;
}
mCurrent = current;
dice.setText("" + mCurrent);
}
/**
* checks for the following errors:
*
* checks string if it is blank, if so changes string to "1"
*
* look at each char in string individually to see if int or not if the char
* is an in add it to stringDice, example: a string of "1.2-3" would result
* in a stringDice of "123"
*
* also if there are any zeros preceding an int, they will be removed
* example: a string of "000102" would result in a stringDice of "102"
*
* if there are any typos removed, use toast to inform the user that we
* assumed that when they typed "0001.2-3" they meant to type "123"
*
* limits stringDice to 3 chars (limiting the number of dice to 999) if
* stringDice is longer than 3 chars, it is changed to "1" also toast is
* displayed to inform user of the 999 dice rule.
*
* @param String
* string
* @return int numDice
* @author ricky barrette * @author ricky barrette
*/ */
public int checkForErrors(String string) { public static void cancelDecrement() {
Log.i(TAG, "checkForErrors()"); mDecrement = false;
int numDice = 0;
char charDice;
StringBuffer stringDice = new StringBuffer();
boolean errors = false;
boolean zeroCheck = true;
boolean isNumber = false;
/**
* if textField is left blank, change value to 1
*/
if (string.length() == 0)
string += "" + 1;
/**
* look at each char in string individually to see if int or not if the
* char is an in add it to stringDice, example: a string of "1.2-3"
* would result in a stringDice of "123"
*
* also if there are any zeros preceding an int, they also will be
* removed example: a string of "00-01.02" would result in a stringDice
* of "102"
*/
for (int i = 0; i < string.length(); i++) {
// get the char
charDice = string.charAt(i);
/**
* try to parse the char, to see it it is an int or not.
*/
try {
/**
* we are going to borrow numDice instead of creating another
* addressing space
*/
numDice = Integer.parseInt(Character.toString(charDice));
// -------------------------------------------------------------------------------------
/**
* zero check to remove any zeros preceding an int value. true =
* zero check on, false = zero check off
*/
if (zeroCheck == true) {
if (numDice != 0) {
zeroCheck = false;
isNumber = true;
stringDice.append(numDice);
}
} else
stringDice.append(numDice);
} catch (NumberFormatException nFE) {
errors = true;
}
}
/**
* notify user if there were no ints
*/
if (isNumber == false) {
toastLong("You inputed: \" "
+ string
+ " \", which contains no numbers, we will roll one dice for you.");
stringDice.append(1);
/**
* prevent error message from displaying
*/
errors = false;
}
/**
* notify user if there were typos
*/
if (errors == true)
toastLong("You inputed: \" " + string
+ " \", we think you meant: "
+ stringDice.toString());
// -----------------------------------------------------------------------------------------
/**
* limit number to 999
*/
if (stringDice.length() > 3) {
toastLong("Sorry, I can not roll " + stringDice
+ " dice. Try Rolling Between 1 - 999 dice.");
/**
* set number of dice to 1
*/
numDice = 1;
} else
numDice = Integer.parseInt(stringDice.toString());
stringDice = null;
System.gc();
return numDice;
} }
/**
* stop incrementing of dice after longpress
* @author ricky barrette
*/
public static void cancelIncrement() {
mIncrement = false;
}
protected void changeCurrent(int current) {
// Wrap around the values if we go past the start or end
if (current > mEnd) {
current = mStart;
} else if (current < mStart) {
current = mEnd;
}
mPrevious = mCurrent;
mCurrent = current;
updateView();
}
/** /**
* clears the rollHistory List array and refreshes the listview * clears the rollHistory List array and refreshes the listview
* *
@@ -223,6 +180,45 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory)); listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory));
} }
private String formatNumber(int value) {
return (mFormatter != null)
? mFormatter.toString(value)
: String.valueOf(value);
}
/**
* @return the current value.
*/
public int getCurrent() {
return mCurrent;
}
private int getSelectedPos(String str) {
if (mDisplayedValues == null) {
return Integer.parseInt(str);
} else {
for (int i = 0; i < mDisplayedValues.length; i++) {
/* Don't force the user to type in jan when ja will do */
str = str.toLowerCase();
if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
return mStart + i;
}
}
/* The user might have typed in a number into the month field i.e.
* 10 instead of OCT so support that too.
*/
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
/* Ignore as if it's not a number we don't care */
}
}
return mStart;
}
/** /**
* also implemented OnClickListener * also implemented OnClickListener
* *
@@ -260,7 +256,12 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
/* /*
* views and listeners * views and listeners
*/ */
dice = (TextView) findViewById(R.id.dice); dice = (EditText) findViewById(R.id.dice);
dice.setOnFocusChangeListener(this);
InputFilter inputFilter = new NumberPickerInputFilter();
mNumberInputFilter = new NumberRangeKeyListener();
dice.setFilters(new InputFilter[] {inputFilter});
listview = (ListView) findViewById(R.id.list); listview = (ListView) findViewById(R.id.list);
NumberPickerButton btAddDice = (NumberPickerButton) findViewById(R.id.up); NumberPickerButton btAddDice = (NumberPickerButton) findViewById(R.id.up);
NumberPickerButton btSubtractDice = (NumberPickerButton) findViewById(R.id.down); NumberPickerButton btSubtractDice = (NumberPickerButton) findViewById(R.id.down);
@@ -284,8 +285,6 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
/* /*
* hide keyboard * hide keyboard
*
* works on the emulator
*/ */
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(dice.getWindowToken(), 0); ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(dice.getWindowToken(), 0);
@@ -309,6 +308,16 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
return true; return true;
} }
public void onFocusChange(View v, boolean hasFocus) {
/* When focus is lost check that the text field
* has valid values.
*/
if (!hasFocus) {
validateInput(v);
}
}
/** /**
* rolls same amount of dice as previous roll * rolls same amount of dice as previous roll
* @author ricky barrette * @author ricky barrette
@@ -341,7 +350,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
return true; return true;
} }
/** /**
* handles menu selection * handles menu selection
* *
* @author WWPowers 3-27-2010 * @author WWPowers 3-27-2010
@@ -361,7 +370,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
} }
/** /**
* resorts application state after rotation * resorts application state after rotation
* @author ricky barrette * @author ricky barrette
*/ */
@@ -376,7 +385,9 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory)); listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory));
} }
/**
/**
* saves application state before rotatoin * saves application state before rotatoin
* @author ricky barrette * @author ricky barrette
*/ */
@@ -391,7 +402,8 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
/**
/**
* displays a quit dialog * displays a quit dialog
* *
* @author ricky barrette 3-28-2010 * @author ricky barrette 3-28-2010
@@ -414,7 +426,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
builder.show(); builder.show();
} }
/** /**
* returns a custom string containing dice rolls and number of successes * returns a custom string containing dice rolls and number of successes
* *
* @param int times * @param int times
@@ -447,7 +459,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
return resultsString.toString(); return resultsString.toString();
} }
/** /**
* Performs a dice roll * Performs a dice roll
* *
* @author ricky barrette * @author ricky barrette
@@ -460,7 +472,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
* get string from dice textfield it convert it into int, while checking * get string from dice textfield it convert it into int, while checking
* for user input errors * for user input errors
*/ */
mCurrent = checkForErrors((dice.getText()).toString()); // mCurrent = checkForErrors((dice.getText()).toString());
// set Dice textfield to finDice // set Dice textfield to finDice
dice.setText("" + mCurrent); dice.setText("" + mCurrent);
@@ -471,7 +483,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory)); listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row, rollHistory));
} }
/** /**
* generates an array containing 10 sided dice rolls * generates an array containing 10 sided dice rolls
* *
* @param int times * @param int times
@@ -488,7 +500,12 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
return roll; return roll;
} }
/** public void setCurrent(int current) {
mCurrent = current;
updateView();
}
/**
* counts each dice roll that is greater than or equal to 7 as a success. 10 * counts each dice roll that is greater than or equal to 7 as a success. 10
* gets another success (for a total of 2) * gets another success (for a total of 2)
* *
@@ -508,7 +525,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
return intSuccesses; return intSuccesses;
} }
/** /**
* displays toast message with a long duration * displays toast message with a long duration
* *
* @param msg * @param msg
@@ -520,7 +537,45 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
} }
/** protected void updateView() {
/* If we don't have displayed values then use the
* current number else find the correct value in the
* displayed values for the current number.
*/
if (mDisplayedValues == null) {
dice.setText(formatNumber(mCurrent));
} else {
dice.setText(mDisplayedValues[mCurrent - mStart]);
}
dice.setSelection(dice.getText().length());
}
private void validateCurrentView(CharSequence str) {
int val = getSelectedPos(str.toString());
if ((val >= mStart) && (val <= mEnd)) {
if (mCurrent != val) {
mPrevious = mCurrent;
mCurrent = val;
}
}
updateView();
}
private void validateInput(View v) {
String str = String.valueOf(((TextView) v).getText());
if ("".equals(str)) {
// Restore to the old value as we don't allow empty values
updateView();
} else {
// Check the new value and ensure it's in range
validateCurrentView(str);
}
}
/**
* starts Vibrator service and then vibrates for x milliseconds * starts Vibrator service and then vibrates for x milliseconds
* *
* @param Long * @param Long
@@ -540,21 +595,4 @@ public class ExaltedDice extends Activity implements OnClickListener, OnLongClic
vib.vibrate(milliseconds); vib.vibrate(milliseconds);
} }
/**
* stop incrementing of dice after longpress
* @author ricky barrette
*/
public static void cancelIncrement() {
mIncrement = false;
}
/**
* stops decrementing of dice after longpress
* @author ricky barrette
*/
public static void cancelDecrement() {
mDecrement = false;
}
} }