格式化

廣告

廣告2

2013年9月26日 星期四

[Android app開發基本概念] listview 無法點擊/無法響應事件/無法獲得焦點

[Android app開發基本概念] listview 無法點擊/無法響應事件/無法獲得焦點

在Android應用設計與實現中我們通常都會使用到ListView這個控件,系統有一些預設的Adapter可以使用,例如SimpleAdapterArrayAdapter,但是總是會有一些情況我們需要通過自定義ListView來實現一些效果,那麼在這個時候,我們通常會碰到自定義ListView無法選中整個ListViewItem的情況,也就是無法響應ListView的onItemClickListener中的onItemClick()方法,究竟是為什麼呢?
我之前也在網上查過不少的資料,但是沒有發現什麼有價值的文章,有一些是建議在Adapter的getView方法中對自己需要響應單擊事件的控件進行設置。但是最終的效果並不是特別理想,而且我認為這是一種取巧的方式,並不推薦。之後自己查看了一下ViewGroup的源碼,發現了以下的一段常量聲明:
    /**
    * This view will get focus before any of its descendants.
    */
    public static final int FOCUS_BEFORE_DESCENDANTS = 0×20000;
    /**
    * This view will get focus only if none of its descendants want it.
    */
    public static final int FOCUS_AFTER_DESCENDANTS = 0×40000;
    /**
    * This view will block any of its descendants from getting focus, even
    * if they are focusable.
    */
    public static final int FOCUS_BLOCK_DESCENDANTS = 0×60000;

    /**     * This view will get focus before any of its descendants.     */

    public static final int FOCUS_BEFORE_DESCENDANTS = 0×20000;
    /**     * This view will get focus only if none of its descendants want it.     */

    public static final int FOCUS_AFTER_DESCENDANTS = 0×40000;
    /**     * This view will block any of its descendants from getting focus, even     * if they are focusable.     */

    public static final int FOCUS_BLOCK_DESCENDANTS = 0×60000;

我們看到了一行代碼定義的變量的意思是「當前View將屏蔽他所有子控件的Focus狀態,即便這些子控件是可以Focus的」,其實這段話的意思就是這個變量代表著當前的View將不顧其子控件是否可以Focus自身接管了所有的Focus,通常默認能獲得focus的控件有 Button,Checkable繼承來的所有控件,這就意味著如果你的自定義ListViewItem中有Button或者Checkable的子類控件的話,那麼默認focus是交給了子控件,而ListView的Item能被選中的基礎是它能獲取Focus,也就是說我們可以通過將ListView 中Item中包含的所有控件的focusable屬性設置為false,這樣的話ListView的Item自動獲得了Focus的權限,也就可以被選中了,也就會響應onItemClickListener中的onItemClick()方法,然而將ListView的Item Layout的子控件focusable屬性設置為false有點繁瑣,我們可以通過對Item Layout的根控件設置其
android:descendantFocusability="blocksDescendant"
即可,這樣Item Layout就屏蔽了所有子控件獲取Focus的權限,不需要針對Item Layout中的每一個控件重新設置focusable屬性了,如此就可以順利的響應onItemClickListener中的 onItenClick()方法了。

沒有留言 :