109

I need to find out if any view is focused inside an Activity and what view it is. How to do this?

Fixpoint
  • 9,619
  • 17
  • 59
  • 78

6 Answers6

134

Call getCurrentFocus() on the Activity.

matiash
  • 54,791
  • 16
  • 125
  • 154
Karan
  • 12,724
  • 6
  • 40
  • 33
13

From the source of Activity:

   /**
     * Calls {@link android.view.Window#getCurrentFocus} on the
     * Window of this Activity to return the currently focused view.
     * 
     * @return View The current View with focus or null.
     * 
     * @see #getWindow
     * @see android.view.Window#getCurrentFocus
     */
    public View getCurrentFocus() {
        return mWindow != null ? mWindow.getCurrentFocus() : null;
    }
Tobrun
  • 18,291
  • 10
  • 66
  • 81
13

Try this instead, put everything inside a thread and print the id and classname live to logcat. Just put this code inside your Activity, in the onCreate method then look into your logcat to see what is currently focused.

JAVA

  new Thread(() -> {
        int oldId = -1;
        while (true) {
            View newView= this.getCurrentFocus();
            if (newView != null && newView.getId() != oldId) {
                oldId = view.getId();
                String idName = "";
                try {
                   idName = getResources().getResourceEntryName(newView.getId());
                 } catch (Resources.NotFoundException e) {
                   idName = String.valueOf(newView.getId());
                 }
                Log.i(TAG, "Focused Id: \t" + idName + "\tClass: \t" + newView.getClass());
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();

KOTLIN

      Thread(Runnable {
            var oldId = -1
            while (true) {
                val newView: View? = this.currentFocus
                if (newView != null && newView.id != oldId) {
                    oldId = newView.id
                    var idName: String = try {
                        resources.getResourceEntryName(newView.id)
                    } catch (e: Resources.NotFoundException) {
                        newView.id.toString()
                    }
                    Log.i(TAG, "Focused Id: \t" + idName + "\tClass: \t" + newView.javaClass)
                }
                try {
                    Thread.sleep(100)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
        }).start()

Be aware this thread runs in a 100ms cycle so it doesn't overflow the CPU with unnecessary work.

Haroun Hajem
  • 5,223
  • 3
  • 26
  • 39
  • You could extend this code and add a highlight so you can see which item is selected. It should work as long the item is inside the screen. But using the `logcat` is much more secure. – Haroun Hajem Nov 16 '20 at 12:24
8

if you are in a fragment you can use

getView().findFocus()
Pablo Johnson
  • 1,044
  • 15
  • 21
6

for some reason getCurrentFocus() method isn't available anymore; probably it's deprecated already, here the working alternative:

View focusedView = (View) yourParentView.getFocusedChild();
John F
  • 685
  • 1
  • 8
  • 18
  • 1
    It is two different methods. getCurrentFocus() is an Activity class method and getFocusedChild() belongs to View class – BoredT Jan 09 '15 at 11:59
  • 2
    @BoredT: `getFocusedChild()` is a method on `ViewGroup`. – gnuf Oct 28 '15 at 00:56
1

ViewGroup has quite convenient method for retrieving focused child:

ViewGroup.getFocusedChild()
Ramps
  • 5,190
  • 1
  • 45
  • 47