androidandroid-edittextonclicklisteneronfocuschangelistener

EditText OnFocusChangeListener() doesn't hide cursor and view


I made an EditText OnFocusChangeListener that supposedly hides the cursor and another view when it's not in focus (i.e. clicking anywhere on the screen aside from the EditText will hide those items). Clicking on the EditText is the only time that will display them.

This is my OnFocusChangeListener for my EditText pageTitle:

pageTitle.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean b) {
        if(b) {
            pageTitle.setCursorVisible(true);
            saveCancelBar.setVisibility(View.VISIBLE);
        } else {
            pageTitle.setCursorVisible(false);
            saveCancelBar.setVisibility(View.GONE);
        }
    }
});

I also made an OnclickListener:

pageTitle.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
        pageTitle.setCursorVisible(true);
        saveCancelBar.setVisibility(View.VISIBLE);
    }
});

The OnClickListener works but not the OnFocusListener. Ideally, pageTitle's cursor and saveCancelBar are initially hidden and will only appear when pageTitle is clicked.

This my XML code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:ignore="missingPrefix"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context="app.wanderast.activity.AddPhotoActivity">

    <LinearLayout
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/back_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/arrow_left"
            android:textSize="20sp"
            android:clickable="true"
            android:textColor="@color/black" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:layout_below="@id/toolbar"
        android:orientation="vertical">

        <EditText
            android:id="@+id/title"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="36dp"
            android:background="@color/transparent"
            android:maxLength="64"
            android:privateImeOptions="nm"
            android:inputType="textNoSuggestions|textMultiLine"
            android:cursorVisible="false"
            app:autoSizeTextType="uniform"
            app:autoSizeMinTextSize="16sp"
            app:autoSizeMaxTextSize="24sp"
            app:autoSizeStepGranularity="4sp"
            android:textColor="@color/grey700"/>

        <View
            android:layout_width="100dp"
            android:layout_height="2dp"
            android:layout_marginTop="3dp"
            android:background="@color/grey700"
            />

        <LinearLayout
            android:id="@+id/sort"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/header"
            android:layout_marginTop="20dp"
            android:clickable="true"
            android:gravity="bottom"
            android:orientation="horizontal"
            android:visibility="gone">

            <TextView
                android:id="@+id/sort_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="3dp"
                android:text="List View"
                android:textColor="@color/grey700"
                android:textSize="14sp"/>

            <TextView
                android:id="@+id/sort_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/chevron_circle_down"
                android:textColor="@color/grey700"
                android:textSize="14sp"/>

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:id="@+id/linearLayout">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/add_photo_layout"
            android:layout_marginTop="150dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:gravity="center"
                android:layout_centerInParent="true">

                <TextView
                    android:id="@+id/placeholder"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="40dp"
                    android:layout_marginEnd="40dp"
                    android:layout_marginBottom="30dp"
                    android:background="@null"
                    android:minLines="0"
                    android:text="Add your first travel moment to your story"
                    android:textAlignment="center"
                    android:textColor="@color/black"
                    android:textSize="20sp" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:gravity="center">

                    <LinearLayout
                        android:id="@+id/capture_photo_button"
                        android:layout_marginBottom="15dp"
                        android:paddingStart="5dp"
                        android:paddingEnd="5dp"
                        android:paddingTop="10dp"
                        android:paddingBottom="10dp"
                        android:layout_width="170dp"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:gravity="center|center_vertical"
                        android:background="@drawable/green_pill_thick">

                        <TextView
                            android:id="@+id/capture_photo_icon"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textSize="18sp"
                            android:text="@string/camera"
                            android:layout_gravity="center_horizontal|center_vertical"
                            android:textColor="@color/green500"
                            android:layout_marginEnd="5dp"/>

                        <TextView
                            android:id="@+id/capture_photo_text"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Capture Moment"
                            android:layout_gravity="center_horizontal|center_vertical"
                            android:textColor="@color/green500"
                            android:textAlignment="center"
                            android:textSize="14sp"/>

                    </LinearLayout>

                    <LinearLayout
                        android:id="@+id/add_photo_button"
                        android:paddingTop="10dp"
                        android:paddingBottom="10dp"
                        android:paddingStart="5dp"
                        android:paddingEnd="5dp"
                        android:layout_width="170dp"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:gravity="center|center_vertical"
                        android:background="@drawable/blue_pill_thick">

                        <TextView
                            android:id="@+id/add_photo_icon"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textSize="18sp"
                            android:text="@string/photo"
                            android:layout_gravity="center_horizontal|center_vertical"
                            android:textColor="@color/blue500"
                            android:layout_marginEnd="5dp"/>

                        <TextView
                            android:id="@+id/add_photo_text"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Add from Gallery"
                            android:layout_gravity="center_horizontal|center_vertical"
                            android:textColor="@color/blue500"
                            android:textAlignment="center"
                            android:textSize="14sp"/>

                    </LinearLayout>

                </LinearLayout>

            </LinearLayout>

        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/list_view_layout"
            android:visibility="gone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:paddingBottom="50dp">

            <ListView
                android:id="@+id/list_view_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:stackFromBottom="true"
                android:transcriptMode="alwaysScroll">

            </ListView>

        </RelativeLayout>

    </LinearLayout>


    <!--Navbar-->
    <LinearLayout
        android:id="@+id/photo_story_navbar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@drawable/navbar"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:visibility="gone">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="right"
            android:paddingStart="15dp"
            android:orientation="horizontal"
            android:layout_marginEnd="10dp">

            <!-- Take Photo Button -->
            <LinearLayout
                android:id="@+id/nav_capture_button"
                android:layout_width="84dp"
                android:layout_height="32dp"
                android:paddingStart="10dp"
                android:orientation="horizontal"
                android:background="@drawable/green_pill_button"
                android:layout_gravity="center_vertical"
                android:gravity="center|center_vertical"
                android:paddingEnd="10dp"
                android:clickable="true">

                <TextView
                    android:id="@+id/nav_capture_icon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="14sp"
                    android:text="@string/camera"
                    android:textColor="@color/green500"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:paddingEnd="5dp"/>

                <TextView
                    android:id="@+id/nav_capture_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Capture"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:textColor="@color/green500"
                    android:textAlignment="center"
                    android:textSize="12sp"/>

            </LinearLayout>

            <!-- Add from Gallery Button -->
            <LinearLayout
                android:id="@+id/nav_gallery_button"
                android:layout_width="84dp"
                android:layout_height="32dp"
                android:paddingStart="10dp"
                android:layout_marginLeft="5dp"
                android:orientation="horizontal"
                android:background="@drawable/blue_pill"
                android:layout_gravity="center_vertical"
                android:gravity="center|center_vertical"
                android:paddingEnd="10dp"
                android:clickable="true">

                <TextView
                    android:id="@+id/nav_gallery_icon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="14sp"
                    android:text="@string/photo"
                    android:textColor="@color/blue500"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:paddingEnd="5dp"/>

                <TextView
                    android:id="@+id/nav_gallery_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Gallery"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:textColor="@color/blue500"
                    android:textAlignment="center"
                    android:textSize="12sp"/>

            </LinearLayout>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="right"
            android:paddingEnd="15dp"
            android:orientation="horizontal">

            <!-- Review button -->
            <LinearLayout
                android:id="@+id/nav_review_button"
                android:layout_width="84dp"
                android:layout_height="32dp"
                android:paddingStart="10dp"
                android:orientation="horizontal"
                android:background="@drawable/red_500_pill"
                android:layout_gravity="right"
                android:gravity="center|center_vertical"
                android:paddingEnd="10dp"
                android:clickable="true">

                <TextView
                    android:id="@+id/nav_review_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Review"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:textColor="@color/red500"
                    android:textAlignment="center"
                    android:textSize="12sp"/>

                <TextView
                    android:id="@+id/nav_review_icon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="14sp"
                    android:text="@string/angle_double_right"
                    android:textColor="@color/red500"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:paddingStart="5dp"/>

            </LinearLayout>

        </LinearLayout>

    </LinearLayout>

    <RelativeLayout
        android:id="@+id/save_cancel_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/linearLayout"
        android:layout_alignParentStart="true"
        android:background="@drawable/black_border_top"
        android:visibility="gone">

        <RelativeLayout
            android:id="@+id/save_title_btn"
            android:clickable="true"
            android:layout_width="84dp"
            android:layout_height="32dp"
            android:layout_alignParentRight="true"
            android:background="@drawable/blue_pill"
            android:layout_marginRight="15dp"
            android:layout_marginTop="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_gravity="fill"
                android:text="Save Title"
                android:textSize="12sp"
                android:textColor="#2196F3"/>

        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/cancel_title_btn"
            android:layout_width="84dp"
            android:layout_height="32dp"
            android:clickable="true"
            android:layout_alignParentRight="true"
            android:background="@drawable/grey_700_pill"
            android:layout_marginRight="105dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="Cancel"
                android:layout_gravity="fill"
                android:textSize="12sp"
                android:textColor="#616161" />

        </RelativeLayout>

    </RelativeLayout>


</RelativeLayout>

Solution

  • If you check the definition of onFocusChange(View v, boolean hasFocus) you will notice that your code must change like this:

    pageTitle.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            if(!hasFocus) {
                pageTitle.setCursorVisible(true);
                saveCancelBar.setVisibility(View.VISIBLE);
            } else {
                pageTitle.setCursorVisible(false);
                saveCancelBar.setVisibility(View.GONE);
            }
        }
    });
    

    This is the code for checking the soft keyboard visibility in Android

    public class MainActivity extends AppCompatActivity
    {
        public static String TAG = MainActivity.class.getSimpleName();
    
        private TextView saveCancelBar;
        private EditText pageTitle;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setListenerToRootView();
    
            saveCancelBar = (TextView) findViewById(R.id.cancel_bar);
            pageTitle = (EditText) findViewById(R.id.title);
    
            pageTitle.setOnFocusChangeListener(new View.OnFocusChangeListener()
            {
                @Override
                public void onFocusChange(View view, boolean hasFocus)
                {
                    ...
                }
            });
        }
    
        public void setListenerToRootView()
        {
            final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
    
            activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
            {
                @Override
                public void onGlobalLayout()
                {
                    Rect r = new Rect();
                    activityRootView.getWindowVisibleDisplayFrame(r);
                    int screenHeight = activityRootView.getRootView().getHeight();
    
                    // r.bottom is the position above soft keypad or device button.
                    // if keypad is shown, the r.bottom is smaller than that before.
                    int keypadHeight = screenHeight - r.bottom;
    
                    Log.e(TAG, "keypadHeight = " + keypadHeight);
    
                    if (keypadHeight > screenHeight * 0.15) {
                        // 0.15 ratio is perhaps enough to determine keypad height.
                        Toast.makeText(getApplicationContext(), "Gotcha!!! softKeyboard open", Toast.LENGTH_SHORT).show();
                    } else {
                        // keyboard is closed
                        Toast.makeText(getApplicationContext(), "Gotcha!!! softKeyboard closed", Toast.LENGTH_SHORT).show();
                        saveCancelBar.setVisibility(View.GONE);
                    }
                }
            });
        }
    }