Is there a way to capture text once # pressed until spacebar is pressed in EditText? Thanks in advance for your help.
First attach addTextChangedListener to your edittext and call a method which will match a particular condition like below:
EditText editText = (EditText)findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
String capturedString = getText(s);
} catch (Exception e) {
e.printStackTrace();
}
}
});
The above code will try to populate capturedString everytime a new character is added to the edittext field.
Now write another function getText() like below:
public String getText(String s) {
String startChar = "#";
String endChar = " ";
String output = getStringBetweenTwoChars(s, startChar, endChar);
System.out.println(output);
}
This method will match the provided string for # and space. If found, it will return the captured string if not found, it will throw an error (This error will be captured in catch block of the above code)
Now finally, write the below function which will intake a character sequence and two charecters and match the charecter sequence with the provided charecters and return the string between them:
public String getStringBetweenTwoChars(String input, String startChar, String endChar) {
try {
int start = input.indexOf(startChar);
if (start != -1) {
int end = input.indexOf(endChar, start + startChar.length());
if (end != -1) {
return input.substring(start + startChar.length(), end);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return input;
}
Hope this helps :)
Related
I am developeing app where i want to change the currency value from one to another, Like i have 2 edittext. one for USD Currency to enter and other for EURO currency to enter.
Now i want to enter value in 1 edittext and the calculated value should display in other and same for the other edit text box.
TextWatcher inputTextWatcher = new TextWatcher()
{
public void afterTextChanged(Editable s)
{
try {
Start_Calculate(""+s.toString());
}
catch (NumberFormatException nfe)
{ //or whatever exception you get
}
//do some handling if you need to
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
};
amountET.addTextChangedListener(inputTextWatcher);
TextWatcher inputTextWatcher1 = new TextWatcher() {
public void afterTextChanged(Editable s)
{
try {
Start_Calculate2(""+s.toString());
}
catch (NumberFormatException nfe)
{ //or whatever exception you get
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
amount2ET.addTextChangedListener(inputTextWatcher1);
FUNCTION ARE HERE:
public void Start_Calculate(String val)
{
String user_input_value="00.00";
try
{
// user_input_value=""+amountET.getText().toString();
user_input_value=""+val;
}
catch(NumberFormatException e)
{
user_input_value="00.00";
}
//*/
if(!user_input_value.equalsIgnoreCase(""))
{
if(user_input_value.length()<11)
{
try
{
user_amount=Double.parseDouble(""+user_input_value);
}
catch(NumberFormatException e)
{
user_amount=00.000;
}
if(user_amount>0)
{
user_amount=user_amount*1.0000001;
total_amount_to_send=((user_amount*to_amount_val)/from_amount_val);
// total_amount_to_send= total_amount_to_send+00.0000;
//String total=new DecimalFormat("##.##").format(total_amount_to_send);
// totalTV.setText(user_amount+" "+fromTV.getText().toString()+" = "+ total+" ("+toTV.getText().toString()+")");
// totalTV.setText(user_amount+" = "+ total);
// String finalVal= df.format(target_currency_val);
//total_calTV.setText("( "+user_amount+" × "+df.format(to_amount_val) +" = "+ total+" )");
String total="00.00";
DecimalFormat df = new DecimalFormat("#.####");
total=""+df.format(total_amount_to_send);
try
{
amount2ET.setText(""+total);//_amount_to_send+"");
}
catch(Exception e)
{
Log.e("Error in Calculate1: ",""+e.getMessage());
}
//showtoast(""+total);//_amount_to_send);
//usdTV.setText(""+user_amount+" ("+fromTV.getText().toString()+")");
//pkrTV.setText(""+ total+" ("+toTV.getText().toString()+")");
}
else
{
}
}
else
{
}
}
}
public void Start_Calculate2(String val)
{
//String user_input_value="0";
//String user_input_value=""+val;
String user_input_value="0";
try
{
//user_input_value=""+amount2ET.getText().toString();
user_input_value=val;
}
catch(NumberFormatException e)
{
user_input_value="00.00";
}
//*/
if(!user_input_value.equalsIgnoreCase(""))
{
if(user_input_value.length()<11)
{
try
{
user_amount=Double.parseDouble(""+user_input_value);
}
catch(NumberFormatException e)
{
user_amount=00.00;
}
if(user_amount>0)
{
user_amount=user_amount*1.0000001;
total_amount_to_send=((user_amount*from_amount_val)/to_amount_val);
// total_amount_to_send= total_amount_to_send+00.0000;
//String total=new DecimalFormat("##.##").format(total_amount_to_send);
// totalTV.setText(user_amount+" "+toTV.getText().toString()+" = "+ total+" ("+fromTV.getText().toString()+")");
// totalTV.setText(user_amount+" = "+ total);
//DecimalFormat df = new DecimalFormat("#.##");
// String finalVal= df.format(target_currency_val);
//total_calTV.setText("( "+user_amount+" × "+df.format(to_amount_val) +" = "+ total+" )");
String total=new DecimalFormat("##.##").format(total_amount_to_send);
try
{
amountET.setText(""+total);//_amount_to_send);
}
catch(Exception e)
{
Log.e("Error in Calculate-2: ",""+e.getMessage());
}
//showtoast(""+total);//_amount_to_send);
//usdTV.setText(""+user_amount+" ("+fromTV.getText().toString()+")");
//pkrTV.setText(""+ total+" ("+toTV.getText().toString()+")");
}
else
{
//totalTV.setText("");
//total_calTV.setText("");
}
}
else
{
//totalTV.setText("");
//total_calTV.setText("");
}
}
}
It is because you get infinite loop.
amount2ET.setText will toggle another "afterTextChanged" let you repeat and repeat call of Start_Calculate.
You should remove the listener before set the text
amountET.removeTextChangedListener(inputTextWatcher)
try
{
amountET.setText(""+total);//_amount_to_send);
}
catch(Exception e)
{
Log.e("Error in Calculate-2: ",""+e.getMessage());
}
amountET.addTextChangedListener(inputTextWatcher);
Or you can set a global flag true when updating so you can dismiss another Start_Calculate:
boolean updating = false;
public void afterTextChanged(Editable s)
{
try {
if (!updating)
Start_Calculate(""+s.toString());
}
catch (NumberFormatException nfe)
{ //or whatever exception you get
}
//do some handling if you need to
}
Inside Start_Calculate:
updating = true;
try
{
amountET.setText(""+total);//_amount_to_send);
}
catch(Exception e)
{
Log.e("Error in Calculate-2: ",""+e.getMessage());
}
updating = false;
I retrieve some phones and emails of a contact via JSONarray, for every one of this elements it creates a new EditText (with the phone or email).
I want to know how to update my JSONobject if user change the phone number, or an email, after that I want to add this JSONobject's to a JSONarray to post to my service.
This is the code where I put elements in EditText's:
try {
multiplesArray = new JSONArray(multiples);
//multiplesUpdatedArray = new JSONArray();
System.out.println(multiplesArray.toString(2));
for (int i=0; i<multiplesArray.length(); i++) {
JSONObject contact = new JSONObject();
String type = multiplesArray.getJSONObject(i).getString("tipo");
String data = multiplesArray.getJSONObject(i).getString("texto");
String id = multiplesArray.getJSONObject(i).getString("id");
if (type.equals("phone")) {
final EditText etPhoneItem = new EditText(this);
etPhoneItem.setText(data);
viewPhonesContainer.addView(etPhoneItem);
} else if (type.equals("email")) {
final EditText etEmailItem = new EditText(this);
etEmailItem.setText(data);
viewEmailContainer.addView(etEmailItem);
}
contact.put("tipo", type);
contact.put("id", id);
contact.put("texto", data);
contact.put("cat", "");
contact.put("cat_id", "");
/*multiplesUpdatedArray.put("tipo");
multiplesUpdatedArray.put(type);
multiplesUpdatedArray.put("id");
multiplesUpdatedArray.put(id);
multiplesUpdatedArray.put("texto");
multiplesUpdatedArray.put(data);*/
}
} catch (JSONException e) {
e.printStackTrace();
}
I try some code with "setOnFocusChangeListener" but it didn't work :-(
Thanks in advance!
Use addTextChangeListener .
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence pCode, int start, int before, int count) {
// change your JSONObject
jsobObject.put("key", "value");
}
#Override
public void afterTextChanged(Editable s) {
}
});
You can do it.
etPhoneItem.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) {
if (s.length() != 0) {
try {
contact.put("number", s.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
Simply you can use textView.addTextChangedListener(yourTextWatcherListener) to get the text when user changes the text. But why update that text in json frequetly, because using TextWatcher you will endup updating the json for each and every character you enter. Updating json frequently is very expensive and very bad practice. Instead of using textwatch listener just form the json when you press the post button.
If you are very clear that you are going to update it frequently, then create pojo classes according to the json structure. Updating the variables of the class is not expensive. Convert the pojo class to json using Jackson when editing is done.
JSON to POJO
**> I have a Edit Text with hint 0.00
Now i want to input text
If i press 5 it should appear 0.05
next if i press 4 it should come like 0.54**
this is the correct answer for my requirement
public static void decimalFormat(final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
String before = "";
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
before = s.toString();
}
#Override
public void afterTextChanged(Editable s) {
if (!before.equalsIgnoreCase(s.toString())
&& !TextUtils.isEmpty(s.toString().trim())) {
before = s.toString();
String tvStr = s.toString();
if (tvStr.contains("-") || tvStr.equals(".")) {
editText.setText("");
}
if (!tvStr.equals("") && !tvStr.equals(".")) {
String cleanString = getFormatedNumber(tvStr, 2);
editText.setText(cleanString);
try {
editText.setSelection(cleanString.length());
return;
} catch (IndexOutOfBoundsException e) {
editText.setSelection(cleanString.length() - 1);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
}
public static String getFormatedNumber(String text, int decimalPoint) {
String cleanString = text.replaceAll("[,.|\\s]", "");
if (TextUtils.isEmpty(cleanString)) {
return "0.00";
}
NumberFormat formatter = new DecimalFormat("#,##0.00");
double number = Double.parseDouble(cleanString) / (long) Math.pow(10.0, decimalPoint);
return formatter.format(number).toString();
}
I get the following error (in logcat) and my app crashes on my android device when i try to delete the number 0.0(double data type value) from the EditText when launched on my device ..
the following is the error message :
The following is the code :
/*
* variables prefixed by 'v' are variables of primitive data type
* variables prefixed by 'et' are edit text
* variables prefixed by 'cl' are changeListeners of watcher data type
*
*/
public class MhrSolankiTipCalc extends Activity {
private static final String BILL_BEFORE_TIP = "BILL_BEFORE_TIP";
private static final String CURRENT_TIP = "CURRENT_TIP";
private static final String FINAL_BILL = "FINAL_AMOUNT";
double vBillAmount, vTipAmount, vFinalBillAmount;
EditText etBillAmount, etTipAmount, etFinalBillAmount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mhr_solanki_tip_calc);
if (savedInstanceState == null) {
vBillAmount = 0.0;
vTipAmount = 0.0;
vFinalBillAmount = 0.0;
} else {
vBillAmount = savedInstanceState.getDouble(BILL_BEFORE_TIP);
vTipAmount = savedInstanceState.getDouble(CURRENT_TIP);
vFinalBillAmount = savedInstanceState.getDouble(FINAL_BILL);
}
etBillAmount = (EditText) findViewById(R.id.billBlankEditView);
etTipAmount = (EditText) findViewById(R.id.tipBlankEditView);
etFinalBillAmount = (EditText) findViewById(R.id.finalEditView);
etBillAmount.addTextChangedListener(clBillAmount);
etTipAmount.addTextChangedListener(clTipAmount);
}
private TextWatcher clBillAmount = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
try {
vBillAmount = Double.parseDouble(s.toString());
} catch (NumberFormatException e) {
vBillAmount = 0.0;
}
catch(NullPointerException e)
{
vBillAmount=0.0;
}
updateBillAndFinalAmount();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
};
private TextWatcher clTipAmount = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try{
vTipAmount = Double.parseDouble(s.toString());
}
catch(NumberFormatException e){
vTipAmount = 0.0;
}
updateBillAndFinalAmount();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
};
public void updateBillAndFinalAmount() {
double vTipAmount = Double
.parseDouble(etTipAmount.getText().toString());
double vBillAmount = Double.parseDouble(etBillAmount.getText()
.toString());
double vFinalBillAmount = vBillAmount + (vBillAmount * vTipAmount);
etFinalBillAmount.setText(String.format("%.02f", vFinalBillAmount));
}
Since you're already parsing vBillAmount and vTipAmount and catching NumberFormatExceptions in your TextWatchers, you don't need to do it again in the updateBillAndFinalAmount() method. This will also fix the NumberFormatException you're getting in this method. Change it to:
public void updateBillAndFinalAmount()
{
double vFinalBillAmount = vBillAmount + (vBillAmount * vTipAmount);
etFinalBillAmount.setText(String.format("%.02f", vFinalBillAmount));
}
Before providing the string value you get from the EditText to parseDouble(), make sure it's not null:
vTipAmount = (s.toString().length > 0 && s.toString() != null)
? Double.parseDouble(s.toString())
: 0.0;
An alternative is to catch all Exceptions instead of just NumberFormatException (it adds a bit minimal overhead though):
try {
vBillAmount = Double.parseDouble(s.toString());
} catch (Exception e) {
vBillAmount = 0.0;
}
in updateBillAndFinalAmount() you call Double.parseDouble with the values of the EditTexts which are empty strings. You should check them like you do in the text watchers
double vTipAmount;
double vBillAmount;
try {
vTipAmount = Double.parseDouble(etTipAmount.getText().toString());
} catch (NumberFormatException e) {
vTipAmount = 0.0;
}
try {
vBillAmount = Double.parseDouble(etBillAmount.getText().toString());
} catch (NumberFormatException e) {
vBillAmount = 0.0;
}
and instead of copy/paste this whole block you can simply write a function that return a double by your specific rules
public static double getDoubleFromString(String s)
{
double d;
try {
d = Double.parseDouble(s);
} catch (NumberFormatException e) {
d = 0.0;
}
return d;
}
and your code will look like
double vTipAmount = getDoubleFromString(etTipAmount.getText().toString());
double vBillAmount = getDoubleFromString(etBillAmount.getText().toString());
Trying to implement simple dictionary. I want to make it so while the user is typing in the EditText box the list to scroll automatically to the best match. I don't want it to filter the list. For example if the user types "s" in the EditText I want the first word that s/he sees under the EditText box to be the first word in the dictionary that starts with "s." But the user should still be able to slide up and down and to be able to see the entire list of words. It is basically like a go to functionality. I used ArrayList to store my list of words. The data is in res/raw/data.xml file. Here is my onCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wordListView = (ListView)findViewById(R.id.wordList);
myEditText = (EditText)findViewById(R.id.myEditText);
words = new ArrayList<Word>();
arrAdap = new ArrayAdapter<Word>(this, android.R.layout.simple_list_item_1, words);
wordListView.setAdapter(arrAdap);
try {
InputStream inSource = getResources().openRawResource(R.raw.data);
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(inSource, null);
NodeList wordsList = doc.getElementsByTagName("eng-bg");
int length = wordsList.getLength();
for(int i = 0; i<length; i++) {
Element entry = (Element)wordsList.item(i);
Element eng = (Element)entry.getElementsByTagName("english").item(0);
Element bul = (Element)entry.getElementsByTagName("bulgarian").item(0);
Element id = (Element)entry.getElementsByTagName("ID").item(0);
String english = eng.getFirstChild().getNodeValue();
String bulgarian = bul.getFirstChild().getNodeValue();
int wordId = Integer.parseInt(id.getFirstChild().getNodeValue());
Word word = new Word(bulgarian, english, wordId);
addNewWord(word);
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wordListView.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
selectedWord = words.get(pos);
showDialog(TRANS_DIALOG);
myEditText.setText(selectedWord.getEnglish());
}
});
myEditText.addTextChangedListener(new TextWatcher(){
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
});
}
Your textWatcher should call your ListView's smoothScrollToPosition method in afterTextChanged. For example, rough idea:
String searchString = s.getText().toString(); //get the EditText's current value
// naive brute-force search, you can definitely be smarter about this, maybe using Java Collections binary-search to find the right spot
for (int i=0; i<words.size(); i++) {
String word = words.get(i).toString() // assuming your Words can call toString()
if (word.startswith(searchString)) {
getListView().smoothScrollToPosition(i);
break;
}
}