new to the site and Android programming so I hope someone can help me out. I am trying to self teach and would consider myself a bit of a noob. Right now I'm more of a consumer of this site, but hopefully can become a contributor.
I have created an EditText within a Fragment where I want to capture a dollar amount / currency value. I am trying to use a BigDecimal but am having a hard time implementing. I have a Class named Transaction where I defined getters and setters as well as my JSON object. For example my getters and setters are implemented:
public BigDecimal getAmount() {
return mAmount;
}
public void setAmount(BigDecimal amount) {
mAmount = amount;
}
and my JSON to Save and Retrieve looks like:
json.put(JSON_AMOUNT, mAmount);
if (json.has(JSON_AMOUNT)) {
mAmount = BigDecimal.valueOf(json.getDouble(JSON_AMOUNT));
}
In my OnCreateView of my fragment, my EditText looks like:
mAmountField = (EditText)v.findViewById(R.id.transaction_amount);
mAmountField.setText((CharSequence) mTransaction.getAmount());
mAmountField.addTextChangedListener(new TextWatcher() {
DecimalFormat dec = new DecimalFormat("0.00");
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().matches("\\$(d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$")) {
String userInput = "" + s.toString().replaceAll("[^\\d]", "");
if (userInput.length() > 0) {
Float in = Float.parseFloat(userInput);
float percent = in/100;
mAmountField.setText("$" + dec.format(percent));
mAmountField.setSelection(mAmountField.getText().length());
}
mTransaction.setAmount(BigDecimal.valueOf());
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
}
});
What I can't figure out is how to save the value entered for mAmountField to my JSON Object. With Strings I just use (For Example):
public void onTextChanged(CharSequence s, int start, int before, int count) {
mTransaction.setDetails(s.toString());
}
But I can't figure out the correct syntax for a BigDecimal. Any help or insight would be greatly appreciated. Thanks in advance!
If you want to save BigDecimal as string to JsonObject you need to use the toString()
json.put(JSON_AMOUNT, mAmount.toString());
and then when you want to get the value back
BigDecimal mAmount= new BigDecimal(json.optString(JSON_AMOUNT,"0"));
ps. you can use getString() instead optString() but I recommend optString() because you can set the default value is the key is not exist.
Another suggestion is using Gson library to convert between json and value, you will can serialize whole object and deserialize it back.
Related
I am using TextChangedListener on a EditText called "deviseValue" and make operations with it to show other values in sellValue and buyValue which are two TextViews, as follows :
deviseValue.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
Double dDeviseValue = Double.valueOf(deviseValue.getText().toString());
Double sellResult = dDeviseValue*dSellValue;
Double buyResult = dDeviseValue*dBuyValue;
sellValue.setText(sellResult.toString());
buyValue.setText(buyResult.toString());
}
});
Everything works fine, BUT, when I remove all value of deviseValue (i.e : EMPTY) .. my app crashes !!
How to handle this situation so when user remove all value, deviseValue become automatically > 1. ?
App crashed because you try to convert a string value from a edittext to the double value. But when you cleared your edittext deviseValue.getText().toString() is ""(empty). That's why you got NumberFormatException.
Try to check deviseValue.getText().toString() before convert it to the double.
For example:
String dDeviseText = etEmail.getText().toString();
Double dDeviseValue = Double.valueOf(dDeviseText.isEmpty() ? "1" : dDeviseText);
And you should prevent input not a numbers characters for this edittext.
In the Android app, I have an EditText which should replace certain strings with values from app data.
for e.g. if user types $username it should get replaced with the name of whichever user is currently logged in.
The Editable parameter in afterTextChanged() method of TextWatcher applied on EditText replaces the $username with correct value but the problem is that after the $username is replaced with actual username if I press any character after that it is appended with username followed by pressed character.
e.g.
Say current logged in username is Joe
a. if the input is Hi this is #username
b. afterTextChanged() changes it to Hi this is Joe
c. Now if I press any other character(say I press g OR space) then text in EditText changes to Hi this is Joeusernameg OR Hi this is Joeusername
How do I get output as in step b?
etTemplateMessage.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
final String strUserNameCode = "$username";
String text = s.toString();
if(text.contains(strUserNameCode)){
int startIndex = text.indexOf(strUserNameCode);
int endIndex = startIndex + strUserNameCode.length();
Editable profileName = new SpannableStringBuilder(FileUtil.getUTF8String(settingDTO.getProfileName()));
s.replace(startIndex, endIndex, profileName);
}
}
});
on your afterTextChange method you should set text to the edit text. And String has replace(CharSequence old, CharSequence new) method you can also use it.
like this,
PublishSubject publishSubject = PublishSubject.create();
publishSubject.debounce(200, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(query -> onTextChanged(query.toString()));
void onTextChanged(String text){
final String strUserNameCode = "$username";
etTemplateMessage.setText(text.replace(strUserNameCode, FileUtil.getUTF8String(settingDTO.getProfileName())));
}
and on your aftertextChange method call publishSubject.onNext( s.toString())
Note that you can achieve this with RxJava.
I am trying to generate a regular expression in Android which can satisfy following conditions:
Edit text can accept:
Alphabet only
Combination of Alphabet and number
Combination of Alphabet and special character
Should not accept:
a. Only Number
b. Only Special character
I tried alot but still, i didn't get any meaningful link. Please try to save my day.
I tried with regular expression (?!^\d+$)^.+$") which only valid alphanumric requirement. I am looking for such regular expression which fullfil my requirement.
It's really simple bro... just clear EditText if the text inside it doesn't have an alphabet .. as you have said ...
Should not accept a. Only Number b. Only Special character
TextWatcher mTextWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
boolean atleastOneAlpha = s.toString().matches(".*[a-zA-Z]+.*");
if (!atleastOneAlpha) {
editText.setText("");
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
mTargetEditText.addTextChangedListener(mTextWatcher);
I want to get result from database if user type some incorrect word, For example the "Ahmed" is stored in database and user types "Ahmad", I want, user get result with "Ahmed". If I use "Like", user must type the exact spell "Ahmed" and if he/she type "Ahmad" the result will be null!
Use pg_trgm extension. Install it for your database using the query:
CREATE EXTENSION pg_trgm;
For this table:
CREATE TABLE test (t varchar);
INSERT INTO test VALUES ('Ahmad');
You can get this results:
SELECT * FROM test WHERE 'Ahmed' % t;
t
-------
Ahmad
(1 row)
SELECT * FROM test WHERE t LIKE 'Ahmed';
t
---
(0 rows)
To implement this idea I use following code:
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count > 2) {
//call your async class through which you can make request for get suggestions.
}
}
public void afterTextChanged(Editable s) {
if (count > 2) {
//call your async class through which you can make request for get suggestions.
}
}
};
I need regex that will allow only Latin characters, digits and all other symbols(but not whitespace)
thanks!
UPDATE:
private boolean loginPassHasCorrectSymbols(String input){
if (input.matches("[A-Za-z0-9\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\>\=\?\#\[\]\{\}\\\^\_\`\~]+$")){
return true;
}
return false;
}
I hope I got them all.
"[A-Za-z0-9\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\>\=\?\#\[\]\{\}\\\\\^\_\`\~]+$"
Edit: I forgot that in Java, the regexes are also strings, so you need to actually escape each \ given in the string using another \. I hope I didn't miss any now.
"[A-Za-z0-9\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\>\\=\\?\\#\\[\\]\\{\\}\\\\\\^\\_\\`\\~]+$"
How about everything not a whitespace?
"^\S+$"
I did this and it works for me .
Either you can block whitespace by mentioning it on Edittext, or you can block on editetext.addtextChangeListner too by pragmatically .
1>
android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm,_,-"
2>
etNewPassword.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (etNewPassword.getText().toString().contains(" ")) {
etNewPassword.setText(etNewPassword.getText().toString().replace(" ", ""));
int iLength = etNewPassword.getText().toString().length();
etNewPassword.setSelection(iLength);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Let me know if any concern.
For find any symbol except whitespace, you can use this code. I hope you find it useful
public static boolean hasAnySymbolExceptWhitespace(String string){
return Pattern.matches("(?=.*[^a-zA-Z0-9] ).*", string);
}
Smooth Kotlin solution which allows English letters with some default symbols. Cyrillic or any other language symbols won't be allowed.
//Allows english with usual symbols
private fun hasNonAllowedSymbols(input: String) : Boolean {
val regex = "[a-zA-Z0-9\\s-#,/~`'!#$%^&*()_+={}|;<>.?:\"\\[\\]\\\\]*"
val pattern = Pattern.compile(regex)
return !pattern.matcher(input).matches()
}