【Android問題集】ListView的item的listSelector在第一次時不起作用

作者:Yogi

福利

想了解買房知識,可以找我的朋友,千里馬(微信:qianlima0068),教你低首付買房。(註明:CSDN的朋友介紹的)

前言:在項目調試中,碰到第一次顯示該界面時,其listSelector不起作用的情況,後面則其作用了。

背景介紹

listSelector.xml的代碼如下

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/shortcut_list_press" android:state_pressed="true" android:state_selected="true"/>
    <item android:drawable="@drawable/shortcut_list_sel" android:state_pressed="false" android:state_selected="true"/>
    <item android:drawable="@drawable/shortcut_list_press" android:state_pressed="true"/>
    <item android:drawable="@drawable/shortcut_list_sel" android:state_selected="true"/>

</selector>

用在listview的item佈局文件(shortcutmenu_dlg_listview_item),代碼如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_root_layout"
    android:layout_width="fill_parent"
    android:layout_height="@dimen/favorite_dlg_item_height"
    android:background="@drawable/shortcut_list_selector"
    android:orientation="vertical" >
      ...(省略中間代碼)
</LinearLayout>

這些代碼的用意是,當listview上的某個item被選中時,其背景是一個帶紅框的圖片(shortcut_list_sel)。
界面顯示的代碼如下

        /**
         * do something when view shows.
         */
        private void initShow() {
            DisplayUtil.setViewFocus(mLvChannel);
            mChannelView.updateView();
            int count = mAdapterChannel.getCount();
            if ((count > 0) && (mSelection >= count)) {
                mSelection = count - 1;
            }
            mLvChannel.setSelection(mSelection);
            mAdapterChannel.setSelection(mSelection);
        }

正常來說,當界面顯示時,listview的選中欄會顯示紅色框背景(shortcut_list_sel)。但是每次此界面第一次顯示時,總是沒有預期的效果。但是後續進行上下操作後,效果又正常了。
好了,背景介紹完畢。下面進入分析階段。

問題分析

listSelector只是第一次不起作用,後面都起作用了,所以應該不是listSelector.xml寫錯了。很可能是沒有滿足listSelector定義的條件。
那麼我們就在onItemSelected中加入以下代碼

Log.d(TAG, "onItemSelected   mLvChannel.getSelectedView() =" +  mLvChannel.getSelectedView());
                    View v = mLvChannel.getSelectedView();
                    if (v != null) {
                        Log.d(TAG, "onItemSelected v.isSelected() =" + v.isSelected());
                    }

最後打印結果是

D/FavoriteGroupManageDialog(23038): FavoriteGroupManageDialog onItemSelected mLvChannel.getSelectedView() =android.widget.LinearLayout{2d822910 V.E….. ..S….. 0,79-775,158 #7f0500fe app:id/item_root_layout}
D/FavoriteGroupManageDialog(23038): FavoriteGroupManageDialog onItemSelected v.isSelected() =false

果然,listview選中的item的狀態是unselected的,所以listSelector不起作用是正常的。那麼,該如何讓這個item的狀態爲selected呢?
只有改我們的java代碼了,再看一眼,java代碼是這麼寫的

        /**
         * do something when view shows.
         */
        private void initShow() {
            DisplayUtil.setViewFocus(mLvChannel); //使得listview獲取焦點
            mChannelView.updateView();
            int count = mAdapterChannel.getCount();
            if ((count > 0) && (mSelection >= count)) {
                mSelection = count - 1;
            }
            mLvChannel.setSelection(mSelection);
            mAdapterChannel.setSelection(mSelection);
        }

我發現在其他界面的顯示函數中,我都把DisplayUtil.setViewFocus(mLvChannel);放在尾端,而且都沒有出現這樣的錯,於是我把這句話放到函數的末端,如下

        /**
         * do something when view shows.
         */
        private void initShow() {
            mChannelView.updateView();
            int count = mAdapterChannel.getCount();
            if ((count > 0) && (mSelection >= count)) {
                mSelection = count - 1;
            }
            mLvChannel.setSelection(mSelection);
            mAdapterChannel.setSelection(mSelection);
            DisplayUtil.setViewFocus(mLvChannel);//轉移到了這裏
        }

一切都正常了。

總結

以前對於先使得listview獲取到焦點還是先setSelection,沒有先後順序的概念。經過這次的出錯,明白了2點。
1.setSelection需要在listview得到焦點之前,這樣其selection所在的view才能真正被selected,否則是unselected的狀態。
2.即使onItemSelected被調用了,也不表示其item的狀態是selected。
另外,每個人的代碼狀況都不一樣,所以我的解決方案並不是一定能解決你的問題,就像我在網上搜索“android listSelector不起作用”,得到的答案並不能解決我的問題。所以,一定要靜下心分析所有的可能性,再逐一驗證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章