I'm creating a PV = nRT calculator that has the user enter any of the three given variables. Without the use of a button, the program will automatically detect that three variables have been given and will calculate the fourth missing variable automatically. This is my code so far:
Thread calculate = new Thread(new Runnable() {
#Override
public void run() {
try {
if (Calculations.isCalcable(pressure.getText().toString(),
volume.getText().toString(),
moles.getText().toString(),
temperature.getText().toString()) == true) {
if (pressure.getText().toString().length() == 0) {
pressure.setText("1010");
} else if (volume.getText().toString().length() == 0) {
volume.setText("1010");
} else if (moles.getText().toString().length() == 0) {
moles.setText("1010");
} else {
temperature.setText("1010");
}
}
} catch (Exception e){
}
}
});
calculate.start();
This doesn't work. Also I'm not sure if I'm actually supposed to use a Thread or not. Here's what happens when I enter three variables (The R variable is a constant):
Imgur
In this case the Temperature text should've changed to "1010".
Here's my isCalcable class:
public class Calculations {
public static boolean isCalcable (String pressure, String volume, String moles, String temperature){
int hasNumber = 0;
if (pressure.length() > 0){
hasNumber++;
}
if (volume.length() > 0){
hasNumber++;
}
if (moles.length() > 0){
hasNumber++;
}
if (temperature.length() > 0){
hasNumber++;
}
if (hasNumber == 3){
return true;
}
return false;
}
}
What do I do?
What you need is to detect whether value has been inputted on the
text fields right? Then have you looked at TextWatcher?
Here is an example on how to use it.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//code
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//code
}
#Override
public void afterTextChanged(Editable s) {
//code
}
});
Basically you apply the TextWatcher to the three fields and watch.
If all three fields have the values you need, then do the calculation.
Maybe you can add global variables to the activity and check these global variables on the onTextChanged() method of the text field, and if three of the variables are already complete, set the value of the fourth one.
Related
The first if statement works but once the value is set too true the second if statement should trigger but it does not see code below:
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
TextView Serial = (TextView) findViewById((R.id.LastSerialScanned));
TextView Location = (TextView) findViewById((R.id.LastLocationScanned));
if(hasSerial == false)// does trigger
{
if(Scan.getText().length() == 8)
{
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
}
if(hasSerial == true)// does not trigger
{
Location.setText(Scan.getText());
hasSerial = false;
}
}
Any idea why? I am sure it is obvious but this is my first time working with android studio so I am just missing something. It also did not trigger when I had a simple else statement there
When the first block
if(hasSerial == false)// does trigger
{
if(Scan.getText().length() == 8)
{
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
}
triggers it changes hasSerial to true and changes Location and Scan to empty strings.
Because hasSerial is now true, this following block:
if(hasSerial == true)// does not trigger
{
Location.setText(Scan.getText());
hasSerial = false;
}
is also executed (in the same call to onTextChanged()) and sets hasSerial back to false.
The other line in this block has no effect, since both Scan and Location have been set to empty strings just before.
What you probably intended to do was something like:
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
TextView Serial = (TextView) findViewById((R.id.LastSerialScanned));
TextView Location = (TextView) findViewById((R.id.LastLocationScanned));
if (!hasSerial) { // does trigger
if (Scan.getText().length() == 8) {
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
} else {
Location.setText(Scan.getText());
hasSerial = false;
}
}
I have a listview in my activity with a textview and an edittext of inputType number, the user will enter numbers in each edit text.There is a textview which displays the sum of all the numbers entered. How do i calculate the sum and show it in the textview as soon as the user enters the amount.
I tried it this way :
holder.tvDonationAmount.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
try {
amount = Integer.parseInt(holder.tvDonationAmount.getText().toString());
} catch (NumberFormatException e) {
e.printStackTrace();
}
addn_array.add(amount);
for (int j = 0; j < addn_array.size(); j++) {
try {
sum += addn_array.get(j);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
});
I tried adding each element after he's entered the number into an Arraylist of Integers and add the elements which throws the error.
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at the line inside for loop sum+ = . .
I also implemented this in my Textwatcher like this
private TextWatcher watcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
try {
amount = Integer.parseInt(holder.tvDonationAmount.getText().toString());
addn_array.add(amount);
} catch (NumberFormatException e) {
e.printStackTrace();
}
Toast.makeText(context, ""+addn_array.get(0), Toast.LENGTH_SHORT).show();
for (int j = 0; j <addn_array.size(); j++) {
try {
sum += addn_array.get(j);
Toast.makeText(context, ""+sum, Toast.LENGTH_SHORT).show();
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
Toast.makeText(context, "" + sum, Toast.LENGTH_SHORT).show();
}
};`
It throws this error.
[![Logcat][1]][1]
Can you please tell me what's wrong with this or can you please suggest any better way if there's any?
Take a look at TextWatchers. You don't need a focus change listener, but a TextWatcher, since it listens to changes you make to the text inside the EditText.
Here is a great example: http://stacktips.com/tutorials/android/android-textwatcher-example
The problem is that in case a NumberFormatException is thrown when parsing amount, amount can be null. Thus, null is added to the list.
try {
amount = Integer.parseInt(holder.tvDonationAmount.getText().toString());
addn_array.add(amount);
} catch (NumberFormatException e) {
e.printStackTrace();
}
This will solve your NullPointerException.
Please do use a TextWatcher like #Gregorio Palamà suggested.
I am using this code to add a dash('-') in a phone number after the 3rd and 4th number. The code is working just fine. My problem is that when I press backspace, I can't remove the dash. I can even add dots and I can delete them if I press backspace, but with dash it's just impossible.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MainActivity.headerName.setText("Verification");
phoneNumber = (EditText) getActivity().findViewById(R.id.phoneEditText);
int grup = 1;
phoneNumber.addTextChangedListener(new TextWatcher() {
int keyDel;
String a= phoneNumber.getText().toString();
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
phoneNumber.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KEYCODE_DEL) {
a = a.replace("-" , "");
phoneNumber.setText(a);
keyDel = 1;
}
return false;
}
});
if (keyDel == 0) {
int len = phoneNumber.getText().length();
if(len == 3 || len == 7) {
phoneNumber.setText(phoneNumber.getText() + "-");
phoneNumber.setSelection(phoneNumber.getText().length());
}
} else {
if(KeyEvent.isModifierKey(KEYCODE_DEL)) {
a = a.replace("-" , "");
phoneNumber.getText().toString().replace("-" , "");
phoneNumber.setText(a);
}
keyDel = 0;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
I'm guessing that your UI widget is formatting its text. So, after you remove the hyphen, the widget is putting it back.
I suggest you leave the widget alone. Instead, when you need to use the phone number, remove the formatting characters from the value.
String.replaceAll("[^\\d]", "")
You would use this code when retrieving the value from the widget for some external use. So, you might have a method
public String getPhoneNumberUnformatted() {...}
That returns only the digits of the widget's value.
I have a TextWatcher set up and working (nearly) exactly as I want it. However, I would like this TextWatcher to stop as soon as the user enters a '.'. The only solution I have found so far crashes the app if the user entirely deletes the text. It is also important that the ENTIRE TextWatcher ends at the moment the user enters a '.'.
I have tried placing the TextWatcher within the loop, however it doesn't seem to work.
private TextWatcher userEnterListener = 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) {
if(after==0) {
shownText = "Please try again";
}
else if(after==1) {
shownText = "A";
}
else if(after==2) {
shownText = "An";
}
else if(after==3) {
shownText = "And";
}
else if(after==4) {
shownText = "Andr";
}
else if(after==5) {
shownText = "Andro";
}
else if(after==6) {
shownText = "Androi";
}
else if(after==7) {
shownText = "Android";
}
else if(after==8) {
shownText = "Android A";
}
else if(after==9) {
shownText = "Android Ap";
}
else if(after==10) {
shownText = "Android App";
}
else {
shownText = "Please try again";
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
recordedString = (s.toString());
update();
}
};
maybe this could work:
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(s.toString().equals("Android App") && start == '.'){
//here add an Empty TextWatcher to the EditText who has this TextWatcher added.
}
recordedString = (s.toString());
update();
}
I'm trying to build temperature converter (F -> C and C -> F).
I have 2 ET fields. when user types in one, the other displays converted value and vice verse.
I understand that similar programs has been build already, but I couldn't find solution.
It works fine for one field, but app closes when I try to edit the other one.
Here is my piece of code:
public class Temp extends Activity implements OnClickListener, OnFocusChangeListener {
private EditText temp_f, temp_c;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.temp);
temp_f = (EditText) findViewById(R.id.temp_f_inp);
temp_c = (EditText) findViewById(R.id.temp_c_inp);
temp_c.setOnFocusChangeListener((OnFocusChangeListener) this);
temp_f.setOnFocusChangeListener((OnFocusChangeListener) this);
}
private TextWatcher tempc = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (temp_c.getText().length() == 0)
{
temp_f.setText("");
} else {
float convValue = Float.parseFloat(temp_c.getText()
.toString());
conv_f = ((convValue - 32) * 5 / 9);
temp_f.setText(String.valueOf(new DecimalFormat(
"##.###").format(conv_f)));
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable s) {
}
};
private TextWatcher tempf = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start,int before, int count) {
// TODO Auto-generated method stub
if (temp_f.getText().length() == 0)
{
temp_c.setText("");
} else {
float convValue = Float.parseFloat(temp_f.getText()
.toString());
conv_c = ((convValue * 9) / 5 + 32);
temp_c.setText(String.valueOf(new DecimalFormat(
"##.###").format(conv_c)));
}
#Override
public void beforeTextChanged(CharSequence s, int start,int count, int after) {}
#Override
public void afterTextChanged(Editable s) {
}
};
#Override
public void onFocusChange(View v, boolean hasFocus) {
if ((v == findViewById(R.id.temp_c_inp)) && (hasFocus==true)) {
temp_c.addTextChangedListener(tempc);
}
else if((v == findViewById(R.id.temp_f_inp)) && (hasFocus==true)){
temp_f.addTextChangedListener(tempf);
}
}
it seems like onTextChanged still holds the values of the first ET that has been modified and when I try to edit the other ET fields, it throws an error.
Any help would be greatly appreciated!
Thank you!
You could try this:
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (v.equals(findViewById(R.id.temp_c_inp))) {
if(hasFocus){
temp_c.addTextChangedListener(tempc);
}else{
temp_c.removeTextChangedListener(tempc);
}
}
else if(v.equals(findViewById(R.id.temp_f_inp))){
if(hasFocus){
I temp_f.addTextChangedListener(tempf);
}else{
temp_f.removeTextChangedListener(tempf);
}
}
}
I haven't tried the code by myself, but I hope it could help you
Logic seems to be a problem.
What I would do is,
1. On text change, do nothing (or just check for valid input values)
2. On focus change, do conversion and populate other text field.
Also, you have some #Override functions which are essentially null functions. Why override?