TextView misbehaving when appending two strings - android

I am working on writing a simple temperature conversion program, to familiarize myself with Android programming. The user types in a number to an EditText, and it converts it from Fahrenheit to Celsius, or vice versa, then puts the answer in a TextView. I want to append a Unicode Celsius/Fahrenheit symbol to the end of the answer before displaying it. When I don't have it appending the symbol, it works fine and displays the correct number, but when it is trying to append the symbol to the end, the output displays all wrong, with a long string of numbers at the end (and still no Unicode symbol).
Here's my code:
This is the converter utility class:
public class ConverterUtil {
//Convert to celsius
public static String convertFahrenheitToCelsius(float fahrenheit) {
float temperature = (fahrenheit - 32) * 5 / 9;
DecimalFormat df = new DecimalFormat("#.#");
return df.format(temperature) + R.string.celsius_symbol;
}
//Convert to fahrenheit
public static String convertCelsiustoFahrenheit(float celsius) {
float temperature = (celsius * 9) / 5 + 32; //Append the unicode Celsius symbol (\u2103), then return
DecimalFormat df = new DecimalFormat("#.#");a
return df.format(temperature) + R.string.fahrenheit_symbol; //Append the unicode Fahrenheit symbol (\u2109), then return
}
}
And this is where I call it:
public void calculateTemperature(){
RadioButton celsiusButton = (RadioButton) findViewById(R.id.button2);
TextView output = (TextView) findViewById(R.id.output);
if (text.getText().length() == 0) {
output.setText("");
return;
}
float inputValue = Float.parseFloat(text.getText().toString());
String outputText = celsiusButton.isChecked() ? ConverterUtil.convertFahrenheitToCelsius(inputValue) : ConverterUtil.convertCelsiustoFahrenheit(inputValue);
output.setText(outputText);
}
If I take out the part where I append the Unicode symbols, it looks like this:
And if I put that back in, I get this:
How do I fix that?

Looks like the resourceID of your fahrenheit_symbol & celsius_symbol are getting appended to your text than the actual character.
Try this,
public class ConverterUtil {
//Convert to celsius
public static String convertFahrenheitToCelsius(Context context, float fahrenheit) {
float temperature = (fahrenheit - 32) * 5 / 9;
DecimalFormat df = new DecimalFormat("#.#");
return df.format(temperature) + context.getResources().getString(R.string.celsius_symbol);
}
//Convert to fahrenheit
public static String convertCelsiustoFahrenheit(Context context, float celsius) {
float temperature = (celsius * 9) / 5 + 32; //Append the unicode Celsius symbol (\u2103), then return
DecimalFormat df = new DecimalFormat("#.#");a
return df.format(temperature) + context.getResources().getString(R.string.fahrenheit_symbol); //Append the unicode Fahrenheit symbol (\u2109), then return
}
}
Change where you call it like this,
public void calculateTemperature(){
RadioButton celsiusButton = (RadioButton) findViewById(R.id.button2);
TextView output = (TextView) findViewById(R.id.output);
if (text.getText().length() == 0) {
output.setText("");
return;
}
float inputValue = Float.parseFloat(text.getText().toString());
String outputText = celsiusButton.isChecked() ? ConverterUtil.convertFahrenheitToCelsius(YourActivity.this, inputValue) : ConverterUtil.convertCelsiustoFahrenheit(YourActivity.this, inputValue);
output.setText(outputText);
}

Change
return df.format(temperature) + R.string.fahrenheit_symbol;
return df.format(temperature) + R.string.celsius_symbol;
to
return df.format(temperature) + getString(R.string.fahrenheit_symbol);
return df.format(temperature) + getString(R.string.celsius_symbol);
R.string.fahrenheit_symbol and R.string.celsius_symbol are both integers. You will need to look up the relevant string resource using Context.getResources().getString().
You will need to pass a Context (such as the calling Activity) to your ConverterUtil.

Related

android how have the value of edittext auto format itself and calculate-able at the same time

I have 2 edittexts and 1 textview. 1 edittext for input the price another one the percentage and the textview will display the result of them both (the price * percentage/100) and i want to make the 1st edittext input(for the price) will change the format of the input and display it on the same edittext with decimal format. For example :
edittext1
100
the user type 100 it will just display 100 ,but when the user type one or more number(S) it will add "," every 3 number
edittext1
1,000
edittext1
10,000
edittext1
100,000
edittext1
1,000,000
and so on
i have the functions, one will autocalculate the value for textview1 , another will convert automatically the input of edittext. However they cant work together because the format for calculation function, it uses int/long/double and for the converter it uses decimalformat . If i use them both the app will crash with javanumberformatexception unable to parse int "1,000"(if we put 1000 into edittext)
my function for autocalculate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simulasikredit);
ethint1 = (EditText) findViewById(R.id.ethint);
etpersen2 = (EditText) findViewById(R.id.etpersen);
textvDP1 = (TextView) findViewById(R.id.textvDP);
etpersen2.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text1 = ethint1.getText().toString();
String text2 = etpersen2.getText().toString();
long input1 = 0;
long input2 = 0;
if(text1.length()>0)
input1 = Long.valueOf(text1);
if(text2.length()>0)
input2 = Long.valueOf(text2);
if (text1.length() != 0) {
long output = (input1 * input2) / 100;
textvDP1.setText(""+output);
}
else if(text2.length() == 0){
textvDP1.setText("");
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
}); }
et stands for edittext, tv stands for textview
and makedecimal function
public void makedecimal(View v)
{
ethint1.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
DigitsKeyListener dkl = new DigitsKeyListener(true,true);
ethint1.setKeyListener(dkl);
ethint1.addTextChangedListener(new TextWatcher(){
private String current = "";
#Override
public void afterTextChanged(Editable s) {
String userInput=s.toString();
if(!userInput.toString().equals(current)){
ethint1.removeTextChangedListener(this);
String cleanString = userInput.replaceAll("[,]", "");
if(cleanString.length()>0){
double parsed = Double.parseDouble(cleanString);
String formated = DecimalFormat.getNumberInstance().format(parsed);
current = formated;
ethint1.setText(formated);
ethint1.setSelection(formated.length());
}else{
ethint1.setText(cleanString);
ethint1.setSelection(cleanString.length());
}
ethint1.addTextChangedListener(this);
}
this makedecimal is android:onClick from ethint , ethint is the id(these two come from 1 edittext)
I need to fulfil a similar requirements before where we need to format the number in thousands and also support fractions.
My approach is to register a TextWatcher format text every time input changed, and provide a public method to get numeric value by stripping separators, which is quite tricky. My solution also caters for locale-specific separator by utilizing DecimalFormatSymbols class.
private final char GROUPING_SEPARATOR = DecimalFormatSymbols.getInstance().getGroupingSeparator();
private final char DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();
...
/**
* Return numeric value repesented by the text field
* #return numeric value or {#link Double.NaN} if not a number
*/
public double getNumericValue() {
String original = getText().toString().replaceAll(mNumberFilterRegex, "");
if (hasCustomDecimalSeparator) {
// swap custom decimal separator with locale one to allow parsing
original = StringUtils.replace(original,
String.valueOf(mDecimalSeparator), String.valueOf(DECIMAL_SEPARATOR));
}
try {
return NumberFormat.getInstance().parse(original).doubleValue();
} catch (ParseException e) {
return Double.NaN;
}
}
/**
* Add grouping separators to string
* #param original original string, may already contains incorrect grouping separators
* #return string with correct grouping separators
*/
private String format(final String original) {
final String[] parts = original.split("\\" + mDecimalSeparator, -1);
String number = parts[0] // since we split with limit -1 there will always be at least 1 part
.replaceAll(mNumberFilterRegex, "")
.replaceFirst(LEADING_ZERO_FILTER_REGEX, "");
// only add grouping separators for non custom decimal separator
if (!hasCustomDecimalSeparator) {
// add grouping separators, need to reverse back and forth since Java regex does not support
// right to left matching
number = StringUtils.reverse(
StringUtils.reverse(number).replaceAll("(.{3})", "$1" + GROUPING_SEPARATOR));
// remove leading grouping separator if any
number = StringUtils.removeStart(number, String.valueOf(GROUPING_SEPARATOR));
}
// add fraction part if any
if (parts.length > 1) {
number += mDecimalSeparator + parts[1];
}
return number;
}
It's quite tedious to elaborate here so I'll only give a link for your own reading:
https://gist.github.com/hidroh/77ca470bbb8b5b556901

Unicode Encoding and Decoding

I want an android code or algorithum which will accept a Marathi text as input and convert the marathi text into unicode code. Also reconvert the unicode into marathi text.
i tried some code like:-
string marathi = "मी लाइक आहे";
UnicodeEncoding ue = new UnicodeEncoding(true,true);
string s1 = BitConverter.ToString(ue.GetBytes(marathi.ToCharArray())).Replace("-", "");
but this code is not working in case of android.
Help me as soon as possible. Thanks in advance.
Convert a string to unicode -
public String toUnicode(String text) {
String txt = "";
for (int i = 0; i < text.length(); i++) {
Log.d("Unicode", (int) text.charAt(i));
txt = txt + "\\" + text.charAt(i);
}
return txt;
}
To convert unicode into string, use -
public String toString(String uni){
String tt = "";
String[] parts = uni.split("\\");
for(String x:parts){
x = "\\" + x;
char un = x.toCharArray()[0];
tt = text + un;
}
return tt;
}

How to add Comma between numbers

I have this code for my calculator:
public void onClick(View v) {
try {
double price = Double.parseDouble(InputPrice.getText()
.toString());
double percent = Double.parseDouble(InputPercent.getText()
.toString());
double priceValue = price * percent / 100.0f;
double percentValue = price - priceValue;
PriceToGet.setText(String.valueOf(priceValue));
PriceToPay.setText(String.valueOf(percentValue));
PriceToGet.setText(String.format("%.02f", priceValue));
PriceToPay.setText(String.format("%.02f", percentValue));
The Input and the Output are coming without commas like this:
Input: 333333333
Output: 134555.44
Output: 17475.66
This was just an example for Output and Input.
How do I like the user see them is:
Input: 333,333,333
Output: 134,555.44
Output: 17,475.66
Thanks
Update:
I added decimal in my onclick code:
DecimalFormat formatter = new DecimalFormat("#,###,###");
I used this code but its closing the App after I press the button:
String PriceToGet = formatter.format(String.format("%.02f", priceValue));
And when I am using this method:
String PriceToGet = formatter.format("%.02f", priceValue);
Its force me to change it to:
String PriceToGet = formatter.format(priceValue);
What to do?
You need to use DecimalFormat
You will find the complete answer here
This is how you can convert one of your integers to strings.
int x = 1000000;
DecimalFormat formatter = new DecimalFormat("#,###,###");
String number_string = formatter.format(x);
System.out.println(number_string);
// Outputs 1,000,000
This JS function from Css Tricks - http://css-tricks.com/snippets/javascript/comma-values-in-numbers/
function CommaFormatted(amount) {
var delimiter = ","; // replace comma if desired
var a = amount.split('.',2)
var d = a[1];
var i = parseInt(a[0]);
if(isNaN(i)) { return ''; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
var n = new String(i);
var a = [];
while(n.length > 3) {
var nn = n.substr(n.length-3);
a.unshift(nn);
n = n.substr(0,n.length-3);
}
if(n.length > 0) { a.unshift(n); }
n = a.join(delimiter);
if(d.length < 1) { amount = n; }
else { amount = n + '.' + d; }
amount = minus + amount;
return amount;
}

Android basic math in textview

I am trying to add two numbers and display them in the textview using this code. The problem here is that it doesn't add the numbers, it just displays the entire string.
CharSequence fnum, snum, symbol;
final TextView CalTextBox = (TextView) findViewById(R.id.MainTextview);
symbol = "+"; // addition selected
fnum = CalTextBox.getText(); // store number into fnum
snum = CalTextBox.getText(); //new number will be added in the code and be stored into snum
CalTextBox.setText(""); // delete whats in the text box
CalTextBox.setText(snum + "" + symbol + "" + fnum); // add two numbers
Well, the '+' operator performs concatenation if used on strings (like in this case). To perform a math operation, you have to convert them to numbers first. I think you can use this:
// Convert the 2 String to integer values
int first = Integer.valueOf(fnum);
int second = Integer.valueOf(snum);
// Compute the sum
int sum = first + second;
// Create the String you can use to display in the TextView
String textToDisplay = String.valueOf(sum);
snum = "2";
fnum = "3";
symbol = "+";
snum + "" + symbol + "" + fnum = "2+3"
Instead you should convert String into integer or double and make appropriate controls such as null or empty, or non-numeric then,
int result = Integer.parseInt(snum) + Integer.parseInt(fnum);
CalTextBox.setText("" + result);
For mathematical operations is best to use int, long or double variable types. Instead of CharSequence use for example int.
to get integer (int) from String (text) use:
int fnum, snum, symbol;
int fnum = Integer.parseInt("10"); or
fnum = Integer.parseInt(CalTextBox.getText());
CalTextBox.setText("" + (snum + symbol + fnum));

Prevent line-break in TextView

In my Android app I have a text view that displays text containing special characters. The TextView somehow automatically breaks strings at the characters '/' and '-'.
For example, the string "aaaaaaa/bbb-ccccc/ddd" is displayed as
aaaaaaa/
bbb-
ccccc/
ddd
However, I would like to display it without any linebreaks except the one at the boundaries of the view, i.e., like this:
aaaaaaa/bb
bb-ccccc/d
dd
Is there any way to deactivate the automatic line-breaks or to escape these characters? I already tried escaping with \uFEFF without success.
Keep your textview attribute
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Define Your string in string.xml
<string name="Username"> aaaaaaa\/bb\nbb\-ccccc\/d\ndd</string>
Maybe this is a solution: https://stackoverflow.com/a/22337074/3472905
I've added the slash as mentioned:
public class WordBreakTransformationMethod extends ReplacementTransformationMethod {
private static WordBreakTransformationMethod instance;
private WordBreakTransformationMethod() {}
public static WordBreakTransformationMethod getInstance() {
if (instance == null) {
instance = new WordBreakTransformationMethod();
}
return instance;
}
private static char[] dash = new char[]{'-', '\u2011'};
private static char[] space = new char[]{' ', '\u00A0'};
private static char[] slash = new char[]{'/', '\u2215'};
private static char[] original = new char[]{dash[0], space[0], slash[0]};
private static char[] replacement = new char[]{dash[1], space[1], slash[1]};
#Override
protected char[] getOriginal() {
return original;
}
#Override
protected char[] getReplacement() {
return replacement;
}
}
Its is a new thing in Android 6.
Try adding this to your TextView xml layout
android:hyphenationFrequency="none"
Android TextView follows the standard Unicode line break algorithm: http://www.unicode.org/reports/tr14/tr14-45.html
Excerpt: / Prevent a break before, and allow a break after
You can work around this by placing the 'word joiner' character (U+2060) after the slashes.
Example from strings.xml:
aaaaaaa/\u2060bbb-ccccc/\u2060ddd
You can also try using android:breakStrategy="balanced" to keep the lines roughly the same length.
this is work's for me in kotlin
object WordBreakTransformationMethod : ReplacementTransformationMethod() {
private val dash = charArrayOf('-', '\u2011')
private val space = charArrayOf(' ', '\u00A0')
private val slash = charArrayOf('/', '\u2215')
private val original = charArrayOf(dash[0], space[0], slash[0])
private val replacement = charArrayOf(dash[1], space[1], slash[1])
override fun getOriginal() = original
override fun getReplacement() = replacement
}
//tv_text is TextView
tv_text.apply {
transformationMethod = WordBreakTransformationMethod
text = item.text
}
There no ready solution and no such thing as "wrap text by letters in TextView" the only way to do it in a good way is to extend TextView and modify Paint's breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth) function.
Also, you can calculate TextView size in pixels, calculate width of one letter in pixels, then find number of letters (X) that will fit in one line and then insert linebreak after each X letters
you probably can use the Lines attribute or its counter-part method setLines(int)
I have tested the following code. You can even convert it into a function:
String specialString = "a/b/-c/d-d";
String[] specialArray = specialString.split("/");
String str = "";
for(int i = 0; i < specialArray.length - 1; i++){
str = str + specialArray[i] + Character.toString((char) 47);
}
str = str + specialArray[specialArray.length - 1];
specialArray = str.split("-");
str = "";
for(int i = 0; i < specialArray.length - 1; i++){
str = str + specialArray[i] + Character.toString((char) 45);
}
str = str + specialArray[specialArray.length - 1];
textView.setText(str);
Now the text does not escape
You can calculate the size of a text this way:
String text = "This is my text";
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(14.0f);
Rect bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
bounds.width() // width in pixels
bounds.height() // height in pixels
Based on these values you could break up the text in pieces and insert newline characters.

Categories

Resources