2015-04-25 43 views
16

Tôi đang cố gắng sử dụng bàn phím để điều hướng qua GridView của các mục. Trong bản demo ngắn, chỉ chứa một GridView (chứa mục xem với android:focusable="true"), bạn có thể thấy rằng không có mục nào lấy tiêu điểm - lưới là thứ cuộn (các mục không chuyển sang màu cam).Điều hướng bằng bàn phím với Android GridView không cuộn lưới

scrolling short demo

Thêm android:descendantFocusability="afterDescendants" cho phép từng hạng mục được tập trung đầu tiên, nhưng vẫn còn, không tiếp tục di chuyển các GridView để bạn có thể điều hướng xuống:

with descendent focusability set

Nhấp vào một mục (bằng chuột hoặc bằng cách bấm Return (Quay lại) nếu mục đã được lấy nét, sau khi sửa lỗi lấy nét con cháu), hãy chuyển một mục màu xanh dương - cho biết nó ở trạng thái được nhấn.

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> 

MyA ctivity.java (với 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; 
     } 

    } 

} 

Trao đổi GridView cho một ListView, mà không thay đổi adapter, hoặc các quan điểm mục/xem mục thuộc tính, sẽ cư xử như mong đợi - mặt hàng có thể được tập trung và ListView sẽ di chuyển ở phía dưới, để tất cả các mục có thể được tập trung chỉ bằng cách nhập bàn phím. Ngoài ra, sử dụng RecyclerView với LinearLayoutManager/GridLayoutManager cũng sẽ hoạt động chính xác.

Tôi đã thử điều này trên API 16 và 22 với cùng kết quả. Tôi đã thử cài đặt thuộc tính android:descendantFocusability trên GridView thành afterDescendents với cùng một kết quả.

+0

Tôi sẽ sử dụng RecyclerView với GridLayoutManager (và ItemDecoration, có tính đến khoảng cách mục, để khoảng cách giữa các mục) để triển khai màn hình như vậy. Câu hỏi này chỉ dành cho sự tò mò! – ataulm

+0

Bạn đã thử 'android: drawSelectorOnTop =" true "'? – Manu

+0

@manu cảm ơn bạn đã trả lời. Vấn đề không phải với bộ chọn/tiêu điểm, nó không có khả năng cuộn (bạn có thể thấy trong gif thứ hai, tôi có thể thấy bộ chọn, nhưng vẫn không thể cuộn). – ataulm

Trả lời

1

Tôi đã thử mã của bạn và nó không hoạt động với GridView, như bạn đã nói, nhưng tôi cũng có một số vấn đề với ListView. ListView cuộn chính xác, nhưng chỉ mục đầu tiên của mỗi trang được tô sáng.

Với những sửa đổi nhỏ này, bạn có thể đạt được hiệu ứng bạn muốn trên cả GridView và ListView.

Remove android:descendantFocusability trong 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" /> 

Di android:focusable trong 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" /> 

Thay đổi android:state_focused-android:state_selected trong 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

được chọn khác với trạng thái được tập trung - xem xét trường hợp bạn muốn đại diện cho các mục thực sự được chọn, ví dụ trong chế độ đa lựa chọn: bạn cũng sẽ cần phải có trạng thái 'đã chọn',' tập trung' và 'đã chọn + tập trung' để có thể truy cập được. – ataulm

+0

điều này làm nổi bật rằng GridView chỉ là rác mặc dù nó không nên chọn mục ('view.setSelected (true)') khi bạn di chuyển qua Grid, nhưng đây là một giải pháp tốt (sử dụng trạng thái được chọn) - có thể dựa vào 'state_checked' cho khi bạn thực sự muốn chọn một mục, thực hiện Checkable trên ItemView và' view.setChecked (true) ', nơi bạn sẽ làm setSelected. Cảm ơn! – ataulm

+0

một nhận xét cuối cùng - tôi đã sai - 'đã chọn' giống nhau, theo khái niệm, như' tập trung' - trong mã nguồn, họ (Google) thậm chí còn xin lỗi vì đã đặt tên! 'setActivated (boolean)' là cái mà tôi tưởng tượng sẽ là 'setSelected (boolean)'. – ataulm

Các vấn đề liên quan