2017年2月11日 星期六

Android ListView 內含 custom view 的 click 事件接收

之前說過, Android 有提供各種 Adapter 出來讓大家可以設定 ListView 當中的內容, 但是當 ListView 中的 item 是自訂的 custom view 的時候, 可能會發現點擊 item 後沒有反應, event listener 沒有被呼叫到, 這是因為在自訂的 custom view 裡面含有類似 CheckBox 或 ImageButton之類的 child view, 這類 view 會截取焦點, 被呼叫到的是這些 child view 的 event listener, 而不是 item 本身的 event listener

這時可以在 custom view 的 root view 加入屬性 descendantFocusability, 並設為 blocksDescendants, 這個屬性的意義是讓 ViewGroup 攔阻 child view 獲取焦點, 這樣就會讓 item 點擊後呼叫到 item 本身的 event listener


但是假如今天又想要某個 child view 的點擊呼叫到他自己的 event listener, 而不是 item 本身的 event listener 呢?這時需要寫好 child view 的 event listener 並單獨 assign 給 child view

通常很多網路資源會使用繼承 Adapter 並 override getView 的方式來實作, 但如果用 SimpleAdapter 的話, 其有提供 ViewBinder 的功能, 不需要繼承便可以實現一樣的目的


只要準備好一個 ViewBinder 並實作 setViewValue 函式, 再 set 給 SimpleAdapter, 系統便會呼叫 setViewValue 來讓使用者設定 custom view 內的 child view, 在 setViewValue 中就可以設定 chlid view 的 event listener
OnCheckedChangeListener myOnCheckedListener = new MyOnCheckedChangeListener();

mAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
    @Override
    public boolean setViewValue(View view, Object o, String s) {
        if (view instanceof AppCompatCheckBox) {
            AppCompatCheckBox cb = (AppCompatCheckBox)view;
            cb.setOnCheckedChangeListener(myOnCheckedListener );

            return true;
        }

        return false;
    }
});

沒有留言:

張貼留言