2015-04-25 2 views
16

Я пытаюсь использовать клавиатуру для навигации по GridView элементов.Навигация на клавиатуре с Android GridView не прокручивает сетку

В краткой демонстрации, содержащей только GridView (содержащий элементы с android:focusable="true"), вы можете видеть, что ни один из элементов не фокусируется - сетка - это вещь, которая прокручивается (элементы не становятся оранжевыми).

scrolling short demo

Добавление android:descendantFocusability="afterDescendants" позволяет каждому пункту быть сосредоточенным первым, но до сих пор, не продолжает прокручивать GridView, так что вы можете перемещаться вниз:

with descendent focusability set

Клик по пункту (с помощью мыши или нажатием кнопки «Возврат», если объект был сфокусирован, после исправления фокусности потомства) элемент синий - указывает, что он находится в нажатом состоянии.

clicking grid items

@ макет/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" /> 

@ макет/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" /> 

@ вытяжке/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> 

MyA ctivity.java (с 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; 
     } 

    } 

} 

Перестановка в GridView для ListView, без изменения адаптера или вид товара/вид атрибуты элемента, будут вести себя, как и ожидалось - элементы могут быть сосредоточены и ListView будет прокручиваться снизу, так что все элементы можно сфокусировать, используя только ввод с клавиатуры. Кроме того, использование RecyclerView с LinearLayoutManager/GridLayoutManager также будет работать правильно.

Я пробовал это по API 16 и 22 с теми же результатами. Я попробовал настройки атрибута android:descendantFocusability на GridView до afterDescendents с тем же результатом.

+0

Я хотел бы использовать RecyclerView с GridLayoutManager (и ItemDecoration, который принимает во внимание пункт пролетах, для интервала элемента), чтобы реализовать такой экран. Этот вопрос просто для любопытства! – ataulm

+0

Вы пробовали 'android: drawSelectorOnTop =" true "'? – Manu

+0

@manu благодарит за ответ. Проблема заключается не в селекторе/фокусе, а в том, что вы не можете прокручивать (вы можете видеть во втором gif, я могу видеть селектор, но все еще не могу прокручивать). – ataulm

ответ

1

Я пробовал ваш код, и он не работает с GridView, как вы сказали, но у меня есть проблема с ListView. ListView прокручивается правильно, но выделяется только первый элемент каждой страницы.

С помощью этих небольших модификаций вы можете добиться желаемого эффекта как для GridView, так и для ListView.

Удалить android:descendantFocusability в 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" /> 

Удалить android:focusable в 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" /> 

Переход от android:state_focused к android:state_selected в 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> 
+0

выбранное состояние отличается от сосредоточенного состояния - рассмотрите также случай, когда вы хотите представлять элементы, которые фактически выбраны, например в режиме множественного выбора: вам также нужно будет иметь доступ к выбранным, «сфокусированным» и «выбранным + сфокусированным». – ataulm

+0

это подчеркивает, что GridView - это всего лишь мусор, но при этом вы не должны выбирать элементы ('view.setSelected (true)') при перемещении по Grid, но это хорошее решение (с использованием выбранного состояния) - может опираться на 'state_checked', когда вы действительно хотите выбрать элемент, реализуя Checkable в ItemView и' view.setChecked (true) ', где вы будете делать setSelected. Благодаря! – ataulm

+0

один последний комментарий - я ошибся - 'selected' - это то же самое, концептуально, как« сфокусировано »- в исходном коде они (Google) даже извиняются за именование! 'setActivated (boolean)' - это тот, который я себе представлял, будет 'setSelected (boolean)'. – ataulm

Смежные вопросы