Search code examples
androidandroid-fragmentsandroid-activityandroid-fragmentactivity

Why doesn't findViewById() in an Activity return the user typed value?


I'm creating an Android app where the scenario is User Sign Up and upon clicking "Sign Up" button , the app sends data to REST API.

activity_sign_up_login.java

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/signUp"
        android:text="@string/sign_up"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/logIn"
        android:text="@string/log_in"
        app:layout_constraintStart_toEndOf="@+id/signUp" />

    <EditText
        android:id="@+id/password"
        android:inputType="textPassword"
        app:layout_constraintTop_toBottomOf="@+id/mobNum" />

    <EditText
        android:id="@+id/mobNum"
        app:layout_constraintTop_toBottomOf="@+id/countryCode" />


</android.support.constraint.ConstraintLayout>

SignUp.java

    public class SignUpLogIn extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final ConnectionStatus connectionStatus = new ConnectionStatus(getApplicationContext());
            if(!connectionStatus.isOnline()){
                connectionStatus.displayMobileDataSettingsDialog(this, getApplicationContext());
            }
            setContentView(R.layout.activity_sign_up_log_in);


            final TextView mobNumberTextView = (TextView) findViewById(R.id.mobNum);
            final TextView passwordTextView = (TextView) findViewById(R.id.password);
            Button signUp = (Button) findViewById(R.id.signUp);


            final String mobNumber = mobNumberTextView.getText().toString();
            final String password = passwordTextView.getText().toString();

            signUp.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(!validateInputFields(mobNumber, password)){
                        Intent checkSignUpStatusIntent = new Intent(getApplicationContext(), CrossCheckSignUpService.class);
                        checkSignUpStatusIntent.putExtra("countryCode", countryCode);
                        checkSignUpStatusIntent.putExtra("confirmMobileNumber", mobNumber);
                        checkSignUpStatusIntent.putExtra("confirmPassword", password);
                        startService(checkSignUpStatusIntent);
                        connectionStatus.showProgress();
                    }
                }
            });
        }

private boolean validateInputFields(String mobNum, String password){
        StringBuffer errors = new StringBuffer();
        int count = 0;
        boolean hasError = false;
        if(mobNum == null || mobNum.isEmpty()){
            ++count;
            errors.append(count + ") Please enter your mobile number");
            errors.append('\n');
            hasError = true;
        }
        if(password == null || password.isEmpty()){
            //cEmail field is empty
            ++count;
            errors.append(count + ") Please enter a password");
            errors.append('\n');
            hasError = true;
        }
        if(hasError){
            Toast.makeText(this, errors.toString(), Toast.LENGTH_LONG).show();
            return true;
        }
        return false;
    }

Inside the onClick(), the values are empty, despite user entering the values.

  1. Why is that?
  2. How to fix it?

Please answer inline.

PS:

I cannot remove final for textView variables above .setOnClickListener

enter image description here


Solution

  • You need to get mobNumber and password from inside the onClick() method:

        signUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
    
        String mobNumber = mobNumberTextView.getText().toString();
        String password = passwordTextView.getText().toString();
    
                if(!validateInputFields(mobNumber, password)){
                    Intent checkSignUpStatusIntent = new Intent(getApplicationContext(), CrossCheckSignUpService.class);
                    checkSignUpStatusIntent.putExtra("countryCode", countryCode);
                    checkSignUpStatusIntent.putExtra("confirmMobileNumber", mobNumber);
                    checkSignUpStatusIntent.putExtra("confirmPassword", password);
                    startService(checkSignUpStatusIntent);
                    connectionStatus.showProgress();
                }
            }
        });
    

    Edit

    There is no need to declare your variables as final if you are using them like this

      TextView mobNumberTextView = (TextView) findViewById(R.id.mobNum);
      TextView passwordTextView = (TextView) findViewById(R.id.password);
    

    and inside onClick()

    String mobNumber = mobNumberTextView.getText().toString();
    String password = passwordTextView.getText().toString();
    

    Edit 2

    I just found your problem.

    In your validateInputFields method you are passing 2 strings, mobNum and password, in your if statement you are trying passing 2 strings to the method, that's ok if(!validateInputFields(mobNumber, password))... But, the two strings you are trying to pass through the method are outside your onClick() so, those values can't be reached and your validateInputFields() method is not getting anything to work.

    Edit 3

    I just see that you have this 2 editTexts in your xml

     <EditText
            android:id="@+id/password"
            android:inputType="textPassword"
            app:layout_constraintTop_toBottomOf="@+id/mobNum" />
    
        <EditText
            android:id="@+id/mobNum"
            app:layout_constraintTop_toBottomOf="@+id/countryCode" />
    

    but your reference states two textViews

     TextView mobNumberTextView = (TextView) findViewById(R.id.mobNum);
     TextView passwordTextView = (TextView) findViewById(R.id.password);
    

    you should add two textViews to your xml, or change that TextView mobNumb.... to

    EditText mobNumber...
    

    Like this

     EditText mobNumberTextView = (EditText) findViewById(R.id.mobNum);
     EditText passwordTextView = (EditText) findViewById(R.id.password);