2015-04-25 9 views
16

Ich versuche, eine Tastatur zu verwenden, um durch eine GridView von Elementen zu navigieren.Tastaturnavigation mit Android GridView scrollt nicht Raster

In der kurzen Demo, die nur eine GridView enthält (enthält Elementansichten mit android:focusable="true"), können Sie sehen, dass keiner der Objekte den Fokus erhält - das Raster ist das, was scrollt (die Elemente werden nicht orange).

scrolling short demo

die android:descendantFocusability="afterDescendants" Hinzufügen ermöglicht es jedem Element zuerst fokussiert werden, aber immer noch, auch weiterhin nicht die Gridview zu bewegen, so dass Sie nach unten navigieren können:

with descendent focusability set

Ein Klick auf ein Element (mit der Maus oder durch Drücken der Eingabetaste, wenn der Gegenstand fokussiert wurde, nach dem Fixieren nach der absteigenden Fokussierung), wird ein Gegenstand blau - wodurch angezeigt wird, dass es sich im gedrückten Zustand befindet.

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" /> 

@ ziehbar/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 (mit 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 die Gridview für eine Listview, ohne den Adapter zu ändern, oder die Artikelansichten/item Ansicht Attribute, verhält sich wie erwartet - Elemente fokussiert werden kann und die Listview scrollt nach unten, so dass alle Elemente mit nur einer Tastatureingabe fokussiert werden können. Außerdem funktioniert die Verwendung eines RecyclerView mit LinearLayoutManager/GridLayoutManager ebenfalls ordnungsgemäß.

Ich habe dies auf API 16 und 22 mit den gleichen Ergebnissen versucht. Ich habe Einstellungen android:descendantFocusability Attribut auf der GridView zu afterDescendents mit dem gleichen Ergebnis versucht.

+0

ich ein RecyclerView mit GridLayoutManager verwenden würden (und einem ItemDecoration, die in Betracht Artikel Spannweiten nimmt, für Punkt-Abstand) einen solchen Bildschirm zu implementieren. Diese Frage ist nur für Neugier! – ataulm

+0

Haben Sie versucht, android: drawSelectorOnTop = "true" '? – Manu

+0

@manu danke für die antwort. Das Problem ist nicht mit dem Selektor/Fokus, es ist mit nicht in der Lage zu scrollen (Sie können in der zweiten GIF sehen, ich bin in der Lage, den Selektor zu sehen, aber immer noch nicht in der Lage zu scrollen). – ataulm

Antwort

1

Ich habe versucht Ihren Code und es funktioniert nicht mit GridView, wie Sie gesagt haben, aber ich habe ein Problem auch mit ListView. Die ListView scrollt korrekt, aber nur das erste Element jeder Seite ist hervorgehoben.

Mit diesen kleinen Änderungen können Sie den gewünschten Effekt sowohl in GridView als auch in ListView erzielen.

entfernen 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" /> 

android:focusable in dummy_item.xml entfernen:

<?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" /> 

ändern android:state_focused-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> 
+0

State ausgewählt ist anders als State konzentriert obwohl - bedenken Sie auch den Fall, wo Sie die tatsächlich ausgewählten Elemente darstellen möchten, z.B im Multi-Select-Modus: Sie müssen auch "ausgewählte", "fokussierte" und "ausgewählte + fokussierte" Zustände haben, um zugänglich zu sein. – ataulm

+0

Dies hebt hervor, dass GridView nur Müll ist - es sollte keine Elemente ('view.setSelected (true)') auswählen, während Sie durch das Grid gehen, aber dies ist eine gute Lösung (mit ausgewähltem Status) - könnte sich darauf verlassen 'state_checked' für den Fall, dass Sie tatsächlich ein Element auswählen möchten, indem Sie Checkable für die ItemView implementieren und' view.setChecked (true) ', wo Sie setSelected ausführen würden. Vielen Dank! – ataulm

+0

ein letzter Kommentar - ich lag falsch - 'selected' ist das gleiche, konzeptionell, als' fokussiert' - im Quellcode entschuldigen sie sich (Google) sogar für die Benennung! 'setActivated (boolean)' ist diejenige, von der ich dachte, dass sie 'setSelected (boolean)' wäre. – ataulm