1. 程式人生 > >android開發 gridview的item與子控制元件焦點問題

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=

"match_parent"

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試試:)