-2

I have this form for the user to fill up and one of the Edit Text is BMI and I was thinking if it is possible to auto fill that BMI Edit Text after the user has enter the Height and Weight without clicking any button. I have Googled and found such thing called Text Watcher. I tried implementing it in my code but when I run the application the Edit Text for the BMI is still empty and so is the database.

package mdad.project;

import com.example.manandhowproject.R;

import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Userreg extends Activity implements TextWatcher {
    SQLiteDatabase db;
    Button btnNext;
    EditText etName, etAge, etHeight, etWeight, etBMI;
    double result;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.userreg);
        etName = (EditText) findViewById(R.id.etName);
        etAge = (EditText) findViewById(R.id.etAge);
        etHeight = (EditText) findViewById(R.id.etHeight);
        etWeight = (EditText) findViewById(R.id.etWeight);
        etBMI = (EditText) findViewById(R.id.etBMI);
        Button button = (Button) findViewById(R.id.btnSignOut);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View V) {
                Toast.makeText(getApplicationContext(), "Log Out Success ! ", Toast.LENGTH_LONG).show();
                Intent msg2 = new Intent(Userreg.this, Login.class);
                startActivity(msg2);
            }
        });

        Button btnNext = (Button) findViewById(R.id.btnNext);
        btnNext.setOnClickListener(new OnClickListener() {
            public void onClick(View V) {
                String name = etName.getText().toString();
                String age = etAge.getText().toString();
                int nAge = new Integer(age).intValue();
                String height = etHeight.getText().toString();
                int nHeight = new Integer(height).intValue();
                String weight = etWeight.getText().toString();
                int nWeight = new Integer(weight).intValue();
                String bmi = etBMI.getText().toString();
                String sql = "insert into UserInfo (Name,Age,Height,Weight,BMI) values( '" + name + "','" + nAge + "','" + nHeight + "', '" + nWeight + "', '" + bmi + "')";
                String result = updateTable(sql);

                Intent msg3 = new Intent(Userreg.this, Regsuccess.class);
                startActivity(msg3);
            }
        });
        String sql = "create table if not exists UserInfo (recld integer PRIMARY KEY autoincrement, Name text, Age text, Height text, Weight text, BMI text )";
        String result = createDatabase(sql, "UserInf.db");
    }

    private void calculate() {

        String height = etHeight.getText().toString();
        int nHeight = new Integer(height).intValue();
        String weight = etWeight.getText().toString();
        int nWeight = new Integer(weight).intValue();
        result = nWeight / (nHeight * nHeight);
        String textResult = "" + result;
        etBMI.setText(textResult);

    }


    String createDatabase(String sql, String dbName) {
        try {
            System.out.println(sql);
            db = SQLiteDatabase.openOrCreateDatabase("sdcard/" + dbName, null);
            db.beginTransaction();
            db.execSQL(sql);
            db.setTransactionSuccessful();
            db.endTransaction();
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
            System.out.println(e.toString());
            return ("error open DB");
        }

        return "";
    }

    String updateTable(String sql) {
        try {
            System.out.println(sql);
            db.beginTransaction();
            db.execSQL(sql);
            db.setTransactionSuccessful();
            db.endTransaction();

        } catch (Exception e) {
            System.out.println(e.toString());
            return ("Error updating DB");
        }
        return ("DB updated");
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.second, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @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) {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub
        calculate();
    }
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Kelvin How
  • 25
  • 9
  • 1
    It's the [first](https://stackoverflow.com/questions/8543449/how-to-use-the-textwatcher-class-in-android) result... –  Jan 29 '18 at 13:35
  • The question was not about how to use `TextWatcher` but was more specific, as it contained other bugs as well that caused the user's code not to work as intended. – Minas Mina Jan 30 '18 at 15:26

2 Answers2

0

You can do this in two ways,

FIRST by using TextWatcher as everyone is giving solution. And,

SECOND way is, by using OnFocusChangeListener for EditText. Here's the example how you can achieve it,

EditText one = findViewById(R.id.one);
EditText two = findViewById(R.id.two);
EditText three = findViewById(R.id.three);

three.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            if (hasFocus){
                Double ONE = Double.parseDouble(one.getText().toString().trim());
                Double TWO = Double.parseDouble(two.getText().toString().trim());
                Double THREE = ONE+TWO;
                three.setText(String.valueOf(THREE));
                Log.i("tag", "onFocusChange: "+THREE);
                //or you can perform any other task
            }
        }
});

As shown in above example, as user set focus on third EditText, it takes the value from first and second EditText and shows the result.

Aditya
  • 3,525
  • 1
  • 31
  • 38
-1

You are missing

etHeight.addTextChangedListener(this);
etWeight.addTextChangedListener(this);

in onCreate().

Also, update your calculate() method as it contains a bug on the calculation of BMI:

private void calculate() {

    try {
        String height = etHeight.getText().toString();
        int nHeight = Integer.parseInt(height);
        String weight = etWeight.getText().toString();
        int nWeight = Integer.parseInt(weight);
        result = nWeight / (nHeight * nHeight);
        String textResult = "" + result;
        etBMI.setText(textResult);
    }
    catch (NumberFormatException e) {
        etBMI.setText("");
    }
}
Minas Mina
  • 2,058
  • 3
  • 21
  • 35
  • Hey, I have added the 2 lines of statement as you advised but now whenever I tried to key in any number on height or weight, the whole app will crash. But it does not crash when I enter alphabets. (I think this is because I set the edittext input value to number only) So can you further advise? Thanks – Kelvin How Jan 29 '18 at 13:45
  • It's because you do not validate the inputs in your `calculate()` method. When the text is invalid, an exception is thrown (which causes the crash). I have updated my answer, check it out. It might need some adjustments, as I haven't run the code. Finally, please accept the answer if it has helped you :) – Minas Mina Jan 29 '18 at 13:52
  • Hi, thanks alot for your advise. Currently I am able to get the autofill working however the value it keeps autofilling is 0 no matter what. Can you please further advise? I'd really appreciate your help – Kelvin How Jan 29 '18 at 13:55
  • Okay, there's another bug. `result` is `double`, but the expression `nWeight / (nHeight * nHeight)` (in `calculate()`) yields an `int`, which causes the result to be 0. Change it to `(double) nWeight / (nHeight * nHeight)`. – Minas Mina Jan 29 '18 at 13:59
  • 1
    Alright so I managed to get it working, thanks alot ! – Kelvin How Jan 29 '18 at 14:10