19

I am trying to develop a Log in page, where I have Username, password and a button. When I click the button for the first time, nothing happens, but when I click the button for the second time, then it works properly. I am confused, why it is happening ?

activity_login.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/splash_bg"
tools:context=".LoginActivity" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="vertical"
android:layout_margin="30dp" >

<EditText
    style="@style/EditText1"
    android:id="@+id/userEditText"
    android:layout_marginBottom="50dp"
    android:inputType="textNoSuggestions"
    android:singleLine="true"
    android:hint="username" />
 <EditText
    style="@style/EditText1"
    android:id="@+id/passEditText"
    android:inputType="textPassword"
    android:layout_marginBottom="50dp"
    android:hint="password" />
<Spinner
    android:id="@+id/locationSpinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:popupBackground="#ffffff"
    style="@style/EditText1"
   android:layout_marginBottom="50dp" />
<Button
   style="@style/Button1"
   android:focusable="true"
   android:focusableInTouchMode="true"
   android:onClick="onLoginClick"
   android:text="continue"
         />

loginActivity.java

 @SuppressLint("DefaultLocale")
    public void onLoginClick(View view) {
        String username = mUserEditText.getText().toString();
        String password = mPassEditText.getText().toString();
        String location = mLocationData.get(
                mLocationSpinner.getSelectedItemPosition()).toLowerCase();
        if (username.isEmpty() || password.isEmpty()) {
            CreatorMessenger
                    .getInstance()
                    .showMessage(this, "Error!!",
                            "You need to enter username and password both to continue!!");
            return;
        }
        User user;
        user = new User(username);/*
                             * }
                                 */
        user.setLocation(location);
        AppManager.getInstance().setLoggedInUser(user);

        APICaller.getInstance().login(username, password, location);
    }
Erfan
  • 163
  • 11
Amit Jayaswal
  • 1,725
  • 2
  • 19
  • 36

5 Answers5

27

You are setting android:focusableInTouchMode="true" Hence on 1st click it receives focus.

Refer Android button - How to set focusable to true and still accept onClick listener on first click?

Community
  • 1
  • 1
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
13

Set this -

android:focusableInTouchMode="true"

to this -

android:focusableInTouchMode="false"

on button.

Explanation - If you'll make the button focusable then on first click the focus is passed to the button, then the click is passed on second touch. EditText is a focusable View which gains focus first and therefore other views must first regain the focus from EditText, unless they do not need focus to work, just like buttons. If you just need the OnClick function, then you don't need focus, so you can spre one extra click.

PS: Although it shouldn't require, but setting android:focusable to false will help too, if the first one doesn't work.

0xC0DED00D
  • 19,522
  • 20
  • 117
  • 184
9

Yes Yes I got the answer, after a lot of RND, I got the solution, I just need to implement setOnClickListener(), and setOnFocusChangeListener(). So I am putting here the solution.

ActivityLogin.java

 buttonLogin= (Button) findViewById(R.id.buttonLogin);
    buttonLogin.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("hello", "hellow");
            String username = mUserEditText.getText().toString();
            String password = mPassEditText.getText().toString();
            String location = mLocationData.get(mLocationSpinner.getSelectedItemPosition()).toLowerCase();
            if(username.isEmpty()||password.isEmpty()){
            popbox();
                return;
            }
            User user;
            user = new User(username);
            user.setLocation(location);
            AppManager.getInstance().setLoggedInUser(user);
            APICaller.getInstance().login(username, password, location);
        }
    });
    buttonLogin.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            v.performClick();
        }
    }
});
}

activity_login.xml

  <Button
        android:id="@+id/buttonLogin"
        style="@style/Button1"

        android:text="continue"
         />
Amit Jayaswal
  • 1,725
  • 2
  • 19
  • 36
  • 1
    So you are basically calling onClick() on OnFocus() method. Disabling focus should have worked the same but glad this worked out. – Aniket Thakur Dec 10 '13 at 13:24
  • Actually works well for my issue. I needed the button to be focusable so that my editText views onFocusChange event gets fired when i click the button, and also i needed the button click event to be fired on the first click. If i remove its focusability, the edittext doesnt lose its focus and its event doesnt fire, and without the focus change listener on the button it had to be pressed twice. so, thank you :) – Tomislav3008 Oct 17 '16 at 13:25
3

if in your xml in button, or img, or liner layout has:

android:focusableInTouchMode="true"

To resolve, just remove this.

Guihgo
  • 632
  • 10
  • 13
1

I suggested to use request focus in the "onCreate()" method.

When you using android:focusableInTouchMode="true" you may don't want the focus catch by an 'EditText' field.

For example: 1. An activity has a view contain -> android:focusableInTouchMode 2. You open a Fragment Dialog, but the back button need click two times to fire it. 3. You should call requestFocus() after the Fragment Dialog onCreateView()