Display formatted view model value - android

I have a TextInputEditText that I bind to a ViewModel MutableLiveData object, like so:
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:text="#={ viewModel.mPhoneNumber }"
android:textColorHint="#color/hint_color"/>
I also have a text watcher to format the edit text so that the phone number can display in the format XXX-XXX-XXXX while the user types it out.
However, I need the value in the view model to be without the dashes. As a test, I removed the textwatcher and I tried to use a converter to change the phone number to be with no spaces - but it just caused an infinite loop. And, I can't seem to be able to find proper documentation on how to do this. Code below:
#InverseMethod("StringToPhone")
public static String phoneToString(TextInputEditText view, String oldValue, String value) {
// Just a test for now
if (view.getText() != null && !view.getText().toString().equals(oldValue)) {
view.setText("BLA" + value);
}
return view.getText().toString();
}
public static String StringToPhone(TextInputEditText view, String oldValue, String value) {
// Was supposed to return input string with no spaces
return oldValue == null ? "" : oldValue.replace(" ", "");
}
with
android:text="#={ Converter.phoneToString(phone, viewModel.mPhoneNumber, viewModel.mPhoneNumber) }"
This caused an infinite loop. Does anyone have a proper example / documentation for how to use the converter? Am I using the complete wrong idea, perhaps this is not what the converter was intended to do?

Related

Remove trailing zeros from currency string android

I tried to convert int to curency format and everything worked as I expected
example 1000 --> Rp1.000
but on certain devices the results are not what I expected
i.e. 1000 --> Rp1.000,00
So the question is how to remove the last 2 extra nolls if the device displays them.
my current code:
public static String toUang(String DigitUang) {
return NumberFormat.getCurrencyInstance(new Locale("in", "ID")).format(Double.parseDouble(DigitUang));
}
The best solution here would probably be to fix your locale settings and handle the presentation there. That being said, you also could probably handle this using a regex replacement:
public static String toUang(String DigitUang) {
return NumberFormat.getCurrencyInstance(new Locale("in", "ID"))
.format(Double.parseDouble(DigitUang))
.replaceAll("[,.]00$", "");
}

How do I set the text of an EditText to an Int?

In an attempt to set an EditText to an Int value, I've tried various ways of converting the Int to a value that the EditText will accept, but all fail:
processButton.setOnClickListener {
var intNo = inputText.text as Int
intNo *= 2
outputText.text = intNo as String // error = "required editable"
outputText.text = intNo.toString() // err: type mismatch
outputText.text = Int.toString(intNo) // type mismatch reqd editable
outputText.text = "What is going on?" // type mismatch reqd editable
}
How can I set the EditText to an Int value?
var a: Int = 12
var s: String = a.toString()
This should work for this.
Try given code it will work. What I am doing here I am converting inputText first to String then Int. After I am multiplying with 2 then I am assigning a value for outputText by converting to string.
processButton.setOnClickListener {
var intNo = inputText.text.toString().toInt()
intNo *= 2
//println(intNo.toString())
val myString = intNo.toString()
// If you using outputText as Editable then use this
outputText.text = SpannableStringBuilder(myString)
}
There are a couple things going on here, and to understand them, let's take a look at the various getText and setText methods that EditText has:
Editable getText()
void setText(CharSequence text)
void setText(#StringRes int resid)
// many other setText methods with buffer options
So what Kotlin does here to let you use property syntax is that it creates a text property. The getter used for the property is obvious, since there's only one. The setter for the property is supposed to be the one that takes a CharSequence parameter (it would make sense, Editable extends CharSequence), but actually trying to assign anything other than an Editable to it won't work. See this issue.
To get to the problem at hand, you can read the value in your EditText and convert it to a String like this:
val input = inputText.text.toString()
Then, you can use the toInt() function from the standard library to convert it to an Int (be aware that this will throw an exception if the String can't be parsed):
val doubled = input.toInt() * 2
And finally, you can set the value of the EditText by calling the setText setter in the traditional Java style, passing in a String:
inputText.text.setText(doubled.toString())
A bit of a mess because of the two-way conversion between String and Int, plus the oddities of how the text property is generated here, but that's the way to do it. If you're bothered by how this looks, you could always hide some of this mechanism behind extension properties.
var num: Int = 5
to convert to string would be
num.toString()

InputType doesn't work when text is set with setText

I have set android:inputType="text|textCapWords" to my EditText. When I type something in the field, the first letter is correctly capitalised, but if I set a full capitalised (or full lowercase) text using the setText() method, the text remains fully capitalised (or in lowercase).
How can I use setText for the text to comply with the input type?
As #Amarok suggests
This is expected behavior. You have to format the text yourself before
using the setText() method
But if you want to format your text just like android:inputType="text|textCapWords you can use the following method:
public static String modifiedLowerCase(String str){
String[] strArray = str.split(" ");
StringBuilder builder = new StringBuilder();
for (String s : strArray) {
String cap = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
builder.append(cap + " ");
}
return builder.toString();
}
and use it like
textView.setText(modifiedLowerCase("hEllo worLd"));
It will convert it like :
Hello World
You can check for your editText Type constants, and add simple .toUpperCase() to the text you're adding, like this:
if(mEditText.getInputType() == TYPE_TEXT_FLAG_CAP_CHARACTERS+ TYPE_CLASS_TEXT)
mEditText.setText("Some text".toUpperCase());
else
mEditText.setText("some text");
More for input types constants can be found here
Use this
EditText.getText().clear();
EditText.getText().append("test");
rather than
EditText.setText("test");
so that the text that has been set follows the input type behavior

android Cannot invoke substring(int, int) on the primitive type long

I have textview which will show large numbers and if the number of digits is larger than 5 I want to make the textview show only 4 digits with dots like this(3544...) I tried but I got this error:
android Cannot invoke substring(int, int) on the primitive type long
here is my code:
EditText EditNumber;
long theNumber;
String str = EditNumber.getText().toString();
theNumber = Long.parseLong(str );
if( theNumber >5)
{
theNumber = theNumber.substring(0,4)+"..."; // the error in this line.
textView1.setText(Long.toString(theSide));
}
else
{
textView1.setText(Long.toString(theNumber));
}
As pointed by Martin Cazares the long does not have substring. Use your string instead of your double value.
EditText EditNumber;
long theNumber;
String str = EditNumber.getText().toString();
if( str.length() > 4) // > 4 digits
{
textView1.setText(str.substring(0,4)+"...");
}
else
{
textView1.setText(str);
}
Hope it helps!
Long.toString(theNumber).substring(x,y);
That should give you the digits you want.
You're trying to do a substring method call on a Long which doesn't have that method. You probably intended to do str.substring(0, 0) instead.
The error is that "long" do not have a substring method, be carefull with primitives, they do not have any methods at all...
If you want to substring do it like this:
String theNumber = str.substring(0,4)+"...";
textView1.setText(theNumber);
But beyond that, you might not even need to do it your self, look at the
android:ellipsis="end" property of the TextView
it will do the ellipsis for you if the size of the TextView is smaller than the actual text.
Regards!

How to check for symbols in EditText in android?

I have a EditText in android where IP Address is supposed to be entered. On click of a button I want to check if the text retrieved from EditText does :
not have any spaces
not have any letters
not empty
contain only numbers
and contain only periods "."
I have this if else condition to check if the user is allowed to go to the next activity but it still has some bugs. I don't know how to allow ONLY periods
if(((ip.length() != 0) || ip.contains(" ") == false || ip.matches("[a-z]+") == false) && (ip.matches("[0-9]+") && ip.contains(".")))
{
next = false;
}
else
{
next = true;
}
You can use this regex to check the input
"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
EDIT:
Do not use regex as things will break when IPv6 comes, use this instead
http://commons.apache.org/validator/apidocs/org/apache/commons/validator/routines/InetAddressValidator.html
Pretty simple with Regular Expression
private static final String PATTERN =
"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
public static boolean validate(final String ip){
Pattern pattern = Pattern.compile(PATTERN);
Matcher matcher = pattern.matcher(ip);
return matcher.matches();
}
I hope it will help you.
Thanks.
This will work:
<EditText
android:inputType="number"
android:digits="0123456789."
/>
allowing only numbers and .
You can do this much elegant by using android.util.Patterns:
import android.util.Patterns
...
boolean isIPvalid (String input) {
return Patterns.IP_ADDRESS.matcher(input).matches();
}

Categories

Resources