Keyboard navigation with Android GridView doesn't scroll grid

I’m trying to use a keyboard to navigate through a GridView of items.

In the short demo, which only contains a GridView (containing item views with android:focusable="true"), you can see that none of the items gain focus – the grid is the thing that scrolls (the items don’t turn orange).

  • Android Ice Cream Sandwich Edittext: Disabling Spell Check and Word Wrap
  • Check if back key was pressed in android?
  • QWebView HTML5 GeoLocation on Android platform
  • How to load images from mipmap folder programatically?
  • START_STICKY, foreground Android service goes away without notice
  • Ionic requests return 404 only on android, in Chrome it works fine
  • scrolling short demo

    Adding the android:descendantFocusability="afterDescendants" allows each item to be focused first, but still, doesn’t continue to scroll the GridView so you can navigate down:

    with descendent focusability set

    Clicking on an item (with mouse or by pressing Return if the item was focused, after the descendent focusability fix) turns an item blue – indicating it’s in pressed state.

    clicking grid items

    @layout/activity_my.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/listview"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:numColumns="2" />
    

    @layout/dummy_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/dummy_item_parent"
      android:layout_width="match_parent"
      android:layout_height="150dp"
      android:gravity="center"
      android:focusable="true"
      android:clickable="true"
      android:background="@drawable/item_background" />
    

    @drawable/item_background.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
      <item android:state_focused="true" android:drawable="@android:color/holo_orange_light" />
      <item android:drawable="@android:color/holo_red_light" />
    </selector>
    

    MyActivity.java (with ListAdapter):

    public class MyActivity extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my);
    
            AbsListView listview = (AbsListView) findViewById(R.id.listview);
            listview.setAdapter(new DummyAdapter(getLayoutInflater()));
        }
    
        private static class DummyAdapter extends BaseAdapter {
    
            private static final int COUNT = 25;
    
            private final LayoutInflater layoutInflater;
    
            DummyAdapter(LayoutInflater layoutInflater) {
                this.layoutInflater = layoutInflater;
            }
    
            @Override
            public int getCount() {
                return COUNT;
            }
    
            @Override
            public String getItem(int position) {
                return "Item " + position;
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = convertView;
                if (view == null) {
                    view = layoutInflater.inflate(R.layout.dummy_item, parent, false);
                }
                ((TextView) view).setText(getItem(position));
                return view;
            }
    
        }
    
    }
    

    Swapping the GridView for a ListView, without changing the adapter, or the item views/item view attributes, will behave as expected – items can be focused and the ListView will scroll to the bottom, so that all items can be focused using just keyboard input. Also, using a RecyclerView with LinearLayoutManager / GridLayoutManager will also work correctly.

    I have tried this on API 16 and 22 with the same results. I have tried settings the android:descendantFocusability attribute on the GridView to afterDescendents with the same result.

    Related posts:

    Android: takePicture() not making sound
    Android duplicate registration id for different devices
    What is the best backport of Android switch widget for 2.2?
    Having trouble animating listview layout
    photo/image-to-sketch algorithm
    java.net.SocketException: sendto failed: EPIPE (Broken pipe) over a data connection to localhost
  • body.setTransform does not work inside contact listener (andEngine and box2d)
  • Android Canvas, multiple paths with different zoom amounts
  • How to use web camera in android emulator to capture a live image?
  • Type 'jint' could not be resolved, and JNIEnv, jclass
  • How to add custom app tag in native android contact app?
  • Android: Firebase token is null at first run
  • One Solution collect form web for “Keyboard navigation with Android GridView doesn't scroll grid”

    I tried your code and it doesn’t work with GridView, as you said, but i have some issue also with ListView. The ListView scrolls correctly, but only the first item of every page is highlighted.

    With these little modifications you can achieve the effect you want on both GridView and ListView.

    Remove android:descendantFocusability in activity_my.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="2" />
    

    Remove android:focusable in dummy_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/dummy_item_parent"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:gravity="center"
        android:clickable="true"
        android:background="@drawable/item_background" />
    

    Change from android:state_focused to android:state_selected in item_background.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
        <item android:state_selected="true" android:drawable="@android:color/holo_orange_light" />
        <item android:drawable="@android:color/holo_red_light" />
    </selector>
    
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.