android開發 gridview的item與子控制元件焦點問題
最近專案中用到了gridview,順帶對gridview的item與子控制元件焦點問題進行小小的研究比較下;
專案需求:在simphone手持把槍上通過方向按鈕實現gridview的選單選擇;
實現方法1:在子佈局中寫入button的background屬性,在gridview中定義descendantFocusability為afterDescendants,讓button優先獲得焦點
ViewGroup.FOCUS_AFTER_DESCENDANTS:表示item的子控制元件優先於item獲得焦點;
ViewGroup.FOCUS_BEFORE_DESCENDANTS:表示item優先於其子控制元件獲得焦點
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/btn"
style="@style/large_white_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bbuton_primary_rounded"
android:text="入庫"/>
</LinearLayout>
<GridView
android:id="@+id/gridView1"
android:layout_width=
android:layout_height="match_parent"
android:numColumns="2"
android:horizontalSpacing="12dp"
android:verticalSpacing="12dp"
android:descendantFocusability="afterDescendants"
android:paddingTop="38dp"
android:paddingLeft="12dp"
android:paddingRight="12dp">
</GridView>
結果:大致達到要求,只是存在問題:1.選單項過多的時候,通過方向鍵向下選擇選單,gridview無法自動滾動 為此,又通過以下方法:在介面卡getview中,監聽btn的狀態,通過狀態變化,改變gridview滾動位置。holder.btn.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
btnFocusChange.onFocusChange(pos,btn);
}
}
});
adapter.setOnBtnFocusChange(new GridViewAdapter.BtnFocusChange() {
@Override
public void onFocusChange(int pos, Button btn) {
Log.e("onFocusChange","" + pos);
btn.setSelected(true);
btn.setFocusable(true);
gridView.setSelection(pos);
}
});
結果:現象有改善,只是還是有問題:1.若有滾動,左右方向鍵需按兩次才能切換選單(原因可能與gridView.setSelection(pos)有關,畢竟這句程式碼焦點是gridview的item項~而不是其子控制元件)2.若選單在完全不可見的情況下,方向鍵無法選擇得到,因此gridview也不可能 滾動;問題多多,所以此路不通,何不換種思路,借鑑listview的啟示。實現方法2:讓gridview的item獲得焦點,設定listSelector屬性gridview_item_selector,item檔案下設定android:descendantFocusability="blocksDescendants"
ListView預設情況
當item有焦點時,item上的button等子控制元件獲取不到焦點;
當子控制元件有焦點時,item無焦點無法響應onItemClick事件
<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:horizontalSpacing="12dp"
android:verticalSpacing="12dp"
android:paddingTop="38dp"
android:listSelector="@drawable/gridview_item_selector"
android:paddingLeft="12dp"
android:paddingRight="12dp">
</GridView>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="1dp"
android:descendantFocusability="blocksDescendants">
<Button
android:id="@+id/btn"
style="@style/large_white_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bbuton_primary_rounded"
android:text="入庫"
android:gravity="center"/>
</LinearLayout>
gridview_item_selector.xml如下<?xmlversion="1.0"encoding="utf-8"?>
<selectorxmlns:android="http://schemas.android.com/apk/res/android">
<itemandroid:state_selected="true">
<shapeandroid:shape="rectangle">
<solidandroid:color="#FFE1E1E1"/>
<strokeandroid:width="1dp"android:color="@color/black"/>
<cornersandroid:radius="@dimen/radius"/>
</shape>
</item>
<itemandroid:state_pressed="true">
<shapeandroid:shape="rectangle">
<solidandroid:color="#FFE1E1E1"/>
<strokeandroid:width="1dp"android:color="@color/black"/>
<cornersandroid:radius="@dimen/radius"/>
</shape>
</item>
<itemandroid:state_focused="true">
<shape>
<solidandroid:color="#FFE1E1E1"/>
<strokeandroid:width="1dp"android:color="@color/black"/>
<cornersandroid:radius="@dimen/radius"/>
</shape>
</item>
<itemandroid:state_active="true">
<shape>
<solidandroid:color="#FFE1E1E1"/>
</shape>
</item>
<item>
<shapeandroid:shape="rectangle">
<solidandroid:color="@color/transparent"/>
</shape>
</item>
</selector>
結果:基本實現用方向鍵選取選單時,gridview會隨選擇滾動,點選OK鍵時,能響應gridView.setOnItemClickListener(this)事件,但是此時發現觸屏下,不用方向鍵手動點選觸發選單時,沒響應(原因:button搶去了gridview的item點選事件) 解決:最後無奈將button控制元件改為TextView,完成了專案需求。<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="1dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="@+id/btn"
style="@style/large_white_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bbuton_primary_rounded"
android:text="入庫"
android:gravity="center"/>
</LinearLayout>
綜上所述,選對實現方法是可以事半功倍的,若是一開始就用方法2,也就不用糾結耗費半天時間;寫出來與大家分享,免得像我一樣繞彎。還有最近剛好做到原因單選,本想用radiobutton實現,現在好像也可用gridview試試:)