Output string with decimal format limited to 2 dp - android

Stuck on this which im sure there is an easy solution to, just cannot work it out!!
I have tried decmialformat, numberformat, string.format() etc and nothing works. .
code below, i want to calculation to just show the output limited to 2 decimal places. Have spent the last 2 hours trying various methods all of which causes the app to crash when run...
Output = (Output1 / (1 -(Output2/100)))
String OutputString = String.valueOf(Output);
Num.setText(OutputString);

Try this :
String OutputString = String.format("%.2f", Output);
Num.setText(OutputString);
String.format() to make sure you only get 2 decimal places in your output.

please try this:
double Output = (Output1 / (1 -(Output2/100d)))
Num.setText(String.format("%.2f",Output));
Hope this solves your problem.
Best regards

If you want to Limit the number of Digits before and after the 'decimal_point' then you can use my solution.
private class DecimalNumberFormatTextWatcher implements TextWatcher{
int pos;
int digitsBeforeDecimal = 6;
int digitsAfterDecimal = 2;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if(s.length() > 2)
pos = start;
else {
pos = start + 2;
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
mEdittext.removeTextChangedListener(this);
String text = s.toString();
if(text!= null && !text.equals("")){
if(!text.contains("$")){ //if it does not contains $
text = "$"+text;
} else {
if (text.indexOf("$") > 0) { //user entered value before $
text = s.delete(0, text.indexOf("$")).toString();
}else {
if(!text.contains(".")){ // not a fractional value
if(text.length() > digitsBeforeDecimal+1) { //cannot be more than 6 digits
text = s.delete(pos, pos+1).toString();
}
} else { //a fractional value
if(text.indexOf(".") - text.indexOf("$") > digitsBeforeDecimal+1){ //non fractional part cannot be more than 6
text = s.delete(pos,pos+1).toString();
}
if((text.length() - text.indexOf(".")) > digitsAfterDecimal+1) { //fractinal part cannot be more than 2 digits
text = s.delete(text.indexOf(".") + 2, text.length() - 1).toString();
}
}
}
}
}
mEdittext.setText(text);
mEdittext.setSelection(pos);
mEdittext.addTextChangedListener(this);
}
}
mEdittext.addTextChangedListener(new DecimalNumberFormatTextWatcher());
This also adds a currency sign as soon as the user types the value.
HOPE THIS HELPS ANYONE.

Related

Prevent whitespace in a string after one is entered

I made a code where user can't enter first space in a string.
User is allowed to enter white space after min 2 characters.
I need to redefine my method so user enters white space once, and only once after the two or more characters. After that it should be prevented. How do I do that?
case UPDATE_NAME:
if (firstName.getText().toString().startsWith(" "))
firstName.setText(firstName.getText().toString().trim());
if (firstName.getText().toString().contains(" "))
firstName.setText(firstName.getText().toString().replace(" ", " "));
int indexOfSpace = firstName.getText().toString().lastIndexOf(" ");
if (indexOfSpace > 0) {
String beforeSpace = firstName.getText().toString().substring(0, indexOfSpace);
String[] splitted = beforeSpace.split(" ");
if (splitted != null && splitted.length > 0) {
if (splitted[splitted.length - 1].length() < 2)
firstName.setText(firstName.getText().toString().trim());
}
}
Use a regex pattern. I made one that should match your requirements.
\S{2}\S*\s\S*\n
Explanation:
\S{2} two non whitespace
\S* n non whitespace
\s a whitespace
\S* n non whitespace
\n newline (i only added that for regexr, you may not need it)
Alternate way:
Iterate over String.charAt(int), return false if there is a whitespace in the first two chars, count all whitespaces, return false if n > 1.
This method should meet your requirements:
private static boolean isValidFirstName(String firstName) {
if (firstName != null && !firstName.startsWith(" ")) {
int numberOfSpaces = firstName.length() - firstName.replace(" ", "").length();
if (firstName.length() < 2 || numberOfSpaces <= 1) {
return true;
}
}
return false;
}
What you need to do is use a TextWatcher
public class CustomWatcher implements TextWatcher {
private String myText;
private int count = 0;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
myText= s;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
//check if there is a space in the first 2 characters, if so, sets the string to the previous before the space
if(s.length() < 3 && s.contains(" "))
s= myText;
//if the length is higher than 2, and the count is higher than 0 (1 space added already), puts the string back if a space is entered
else if(s.contains(" ") && count > 0)
s= myText;
//If none of the above is verified and you enter a space, increase count so the previous if statement can do its job
else if(s.contains(" "))
count++;
}
}
And then, set it to your EditText
mTargetEditText.addTextChangedListener(new CustomWatcher());
You can control your editText(I assume) with a TextWatcher, you would only need to check inside afterTextChanged() if length is <2 and else if the string contains the char " ".

Set max length to EditText layout_width

I'm currently doing an EditText where the user can type in one row of text. But I have the issue with setting it's max length. If I set it to a specific number it becomes very unpredictable since spaces takes up more for some reason. So I can type in "asdnknfoisanfo" etc and get the correct length I want, but when you start typing with spaces between the words the length get's smaller and doesn't fill the whole EditText.
<EditText
android:id="#+id/imageDescriptionTextEdit"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="Enter a description of this picture.."
android:textSize="15sp"
android:textColorHint="#E9E9E9"
android:textColor="#ffffff"
android:maxEms="26"
android:imeOptions="actionDone"
android:typeface="monospace"
android:minEms="3"
android:singleLine="true"
fontPath="fonts/VarelaRound-Regular.ttf"
tools:ignore="MissingPrefix"/>
What I would say to be the ultimate solution is to set the length of characters to the length of the EditText itself. Then for sure, the user have the correct capacity always. Is this possible? Or are there another solution to my problem?
You can try with this.
String mStringStr = mEditText1.getText().toString().replaceAll("\\s", "");
Now you can get the actual length in string mStringStr(Without blank space)
mStringStr.length();
I hope this may help you.. :)
Try with this conditional
if(findViewById(R.id.imageDescriptionTextEdit).getText().toString().trim().length() <= "your max length here"){
//Do something
} else {
//Show alert message
}
What you can do is to remove the spaces from the input using below code
String input = Your_EditText.getText().toString();
input = input.replace(" ", "");
Then you can get the length of the string using
int inputlength = input.length();
Then you can check if the input is okay or not
so , overall the code should be
private final TextWatcher mywatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
String input = Your_EditText.getText().toString();
input = input.replace(" ", "");
int inputlength = input.length();
if(inputlength>your_defined_length)
{
//do what you want to do
}
}
public void afterTextChanged(Editable s) {
}
};
Dont forget to add this watcher to your editText
Your_EditText.addTextChangedListener(mywatcher);
You can try it programatically :
final EditText et = (EditText)findViewById(R.id.editText);
et.addTextChangedListener(new TextWatcher() {
int yourMaxLength = 10;
boolean canNotAddMore = false;
String maxText = "";
public void afterTextChanged(Editable s) {
if(canNotAddMore){
et.removeTextChangedListener(this);
et.setText(maxText);
et.addTextChangedListener(this);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
String realCoontent = s.toString().trim().replace(" ", "");
if(realCoontent.length() >= yourMaxLength){
canNotAddMore = true;
maxText = s.toString();
}
}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
This example will remove the spaces from the list of characters counted to determine if the max number of characters is reached.
For example for a limit of 10 characters, the user can enter :
"1234567890"
or
"1 2 3 4 5 6 7 8 9 0"
You can measure the width of the typed input text with a Paint object:
EditText input = findViewById(R.id.imageDescriptionTextEdit) // Your EditText
final Paint paint = input.getPaint();
float textWidth = paint.measureText(input.getText().toString());
if (textWidth > input.getWidth()) {
// Prevent further input.
}
You can combine this check with a TextWatcher.

Android edit text limit

I have an edit text in my android application and I want to avoid from the user to enter an input when the string length in bytes reaches to the limit.
It works fine in english, but not in hebrew.
The limit is 256, so when the input is in hebrew, I can insert only 128 characters. The problem is while I insert hebrew letters with punctuation.
Lets say that I insert a dot, which is 1 byte, it allows me to enter more than 128 characters , even when the characters are only hebrew letters and punctuation.
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = s.toString().getBytes().length;
if (length == bytes_limit)
{
str = s.toString();
}
else if (length > bytes_limit)
{
input.setText(str);
input.setSelection(str.length());
}
}
Update:
String example: "שלום, מה שלומך"
Update 2:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = s.toString().getBytes().length;
if (length <= bytes_limit)
{
str = s.toString();
}
else if (length > bytes_limit)
{
input.setText(str);
input.setSelection(str.length());
}
}
Try specifying the charset eg
int length = s.toString().getBytes("UTF-8").length;
replacing UTF-8 with the character set that you need
See
bytes of a string in java?
And
Will String.getBytes("UTF-16") return the same result on all platforms?
Punctuations are characters too, you write them in addition to the hebrew letter you want to write (if i am not wrong, you can add them with ALT + XXXX).
They are character like any others so when you write them, you are adding characters.
A dot(.) doesn't have punctuation so it takes only one byte.
To solve it, you can remove all of the punctuatuion.
You can create a function to ignore all the punctuation:
private String removePunctuation(String s)
{
for(int i = 0; i < s.length(); i++)
{
if(!(s.charAt(i) <= 'ת' && s.charAt(i) >= 'א'))
{
s = s.substring(0,i) + s.substring(i+1);
}
}
return s;
}
note the it will delete all of the punctuation, including - and : and so on...
You can add exceptions to the condition, enabling '-' or others.
Good luck :)

runtime TextWatcher control

I have 4 edittext and i would like to implement a TextWatcher with a control value.
Et1Burro.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable value) {
// you can call or do what you want with your EditText here
Dvalue = GetEditValue(value);
double et4tot = 0, et2fibra = 0, et3zucc = 0;
// et1burro + et2fibra = et4tot
// et1burro + et2fibra + et3zucc = 100
try {
et4tot = Double.parseDouble(Et4Tot.getText().toString());
} catch (NumberFormatException e) { e.printStackTrace(); }
try {
et2fibra = Double.parseDouble(Et2Fibra.getText().toString());
} catch (NumberFormatException e) { e.printStackTrace(); }
try {
et3zucc = Double.parseDouble(Et3Zucc.getText().toString());
} catch (NumberFormatException e) { e.printStackTrace(); }
if ((Dvalue < 1) || (Dvalue > 100) || ((Dvalue + et2fibra) != et4tot ) || ((Dvalue + et2fibra + et3zucc) != 100 ))
{
//segnala errore
Et1Burro.setTextColor(getActivity().getBaseContext().getResources().getColor(R.color.Red));
}else
Et1Burro.setTextColor(getActivity().getBaseContext().getResources().getColor(R.color.Black));
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
i would like to have a red number if the range number is wrong and a black number if is correct.
I think is better to implement a AsynckTask for control the number or not?
for example the 4 edittext value are:
A,B,C,D
the relation for correct value are:
A+B = D
A+B+C = 100
C = 100 - D
correct example value are A=35, B=35, C=30, D=70
but if in teh first edit (A) the user insert the first caracter ex 35 the program respond with RED value because the other value are 0, and when the user compile all the edittext with the value 35,35,30,70 the anly value that are Black is the last.
I hope to be clear...
Because you are updating only one edit text's color
What i would suggest is,
Set default color to RED for all edit texts
Write a function for your "control value" logic. Call this function only when there are values in all edit texts.
Update all the editbox's color to black if the values entered are passing your control logic. Else you have to set it to RED

How to type decimal values (money) from right to left?

Suppose when a field is loaded, its empty. When the user types 1, it says 0.01, then he types another 0 after the 1 (10) it becomes 0.10. When he types another 1, it becomes 1.10.
Just like entering the price of a product. How do I do that on Android? I'm quite stumped to be honest since I've never tried something like this. Is there some special input method for this?
Here's the code I wrote for myself:
private String addCurrencySign(String digits) {
String string = "£";
// Amount length greater than 2 means we need to add a decimal point
if (digits.length() > 2) {
String pound = digits.substring(0, digits.length() - 2); // Pound part
String pence = digits.substring(digits.length() - 2); // Pence part
string += pound + "." + pence;
} else if (digits.length() == 1) {
string += "0.0" + digits;
Log.d(TAG, "length 1 " + string);
} else if (digits.length() == 2) {
string += "0." + digits;
Log.d(TAG, "length 2 " + string);
}
return string;
}
This addCurrencySign method is triggered each time when user trying to type on the number pad. The number pad is consist of several digit buttons (just like POS handheld or calculator).
Since you don't need to build a keypad with buttons, could you try intercept the keyboard events, which is described in Handling Keyboard Actions and maybe write something like this:
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_0:
return true;
case KeyEvent.KEYCODE_1:
return true;
case KeyEvent.KEYCODE_2:
return true;
case KeyEvent.KEYCODE_3:
return true;
......
default:
return super.onKeyUp(keyCode, event);
}
}
Maybe you don't have to use switch clause, my idea is to intercept the key entering 0~9 digits and for each 0~9, call addCurrencySign method.
Use:
TextWatcher watcher = new TextWatcher(){
afterTextChanged(Editable s){}
beforeTextChanged(CharSequence s, int start, int count, int after){}
onTextChanged(CharSequence s, int start, int before, int count){}
}
yourEditText.addTextChangedListener(watcher);
Here you will find more info about TextWatcher http://developer.android.com/reference/android/text/TextWatcher.html
OK guys.. I have a temporary workaround. This can't be termed as the perfect solution but its a workaround that works well in my case.
I couldn't figure out a way to stop the stackoverflow error. My workaround? Make the EditText field take input, but display the currency output onto a TextView, and make the EditText disappear from the UI so the user can't see that he is typing just 1234 instead of 12.34.
Here is the code. The addCurrencySign function comes from #ss1271.
amountpaid.addTextChangedListener(new TextWatcher()
{
#Override public void onTextChanged(CharSequence s, int start, int before, int count)
{
amount.setText(addCurrencySign(s.toString()));
}
#Override public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override public void afterTextChanged(Editable s)
{
}
});
Here's the function that the user posted. It works very well.
private String addCurrencySign(String digits)
{
String string = "&"; // Your currency
// Amount length greater than 2 means we need to add a decimal point
if (digits.length() > 2)
{
String pound = digits.substring(0, digits.length() - 2); // Pound
// part
String pence = digits.substring(digits.length() - 2); // Pence part
string += pound + "." + pence;
}
else if (digits.length() == 1)
{
string += "0.0" + digits;
Log.d("TextWatcher", "length 1 " + string);
}
else if (digits.length() == 2)
{
string += "0." + digits;
Log.d("TextWatcher", "length 2 " + string);
}
return string;
}
Here's the 'invisible' edittext:
<EditText
android:id="#+id/amoundpaid"
android:layout_width="1dp"
android:layout_height="1dp"
android:background="#00000000"
android:ems="10"
android:inputType="number"
android:textColor="#00ffffff" >
<requestFocus />
Here's the field that will show the output text (with currency sign and proper decimal point value):
<TextView
android:id="#+id/amount"
android:layout_width="210dp"
android:layout_height="50dp"
android:background="#80000000"
android:gravity="center|center_vertical"
android:textColor="#ffffff"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
I know this is not a optimum solution, but it works. I needed the functionality and this is what I had to do to get it. If someone can fix the stackoverflow error, please post and mods will change the answer to that one (once its verified).

Categories

Resources