自定義Android的ListView佈局和各Item的背景色

Android中的ListView是用得很是頻繁的一種組件,同時ListView也是一種很強大的組件,你能夠爲每一行自定義佈局,也能夠修改各行的 背景色。自定義佈局比較容易,本身實現一個layout的佈局文件,而後在adapter的getView裏讀入就能夠了。須要注意的是,在 getView中不須要每次都加載layout文件,由於ListView會重複利用已生成的Item。因此每次拖動上下滾動條的時候其實每行的Item 變化的只是顯示的內容,就窗體自己而言是不變的,Android SDK裏自帶的例子是最好的說明。
      
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  /**
         * Make a view to hold each row.
         *
         * @see android.widget.ListAdapter#getView(int, android.view.View,
         *      android.view.ViewGroup)
         */
        publicView getView(intposition, View convertView, ViewGroup parent) {
            // A ViewHolder keeps references to children views to avoid unneccessary calls
            // to findViewById() on each row.
            ViewHolder holder;
            // When convertView is not null, we can reuse it directly, there is no need
            // to reinflate it. We only inflate a new View when the convertView supplied
            // by ListView is null.
            if(convertView ==null) {
                convertView = mInflater.inflate(R.layout.list_item_icon_text,null);
                // Creates a ViewHolder and store references to the two children views
                // we want to bind data to.
                holder =newViewHolder();
                holder.text = (TextView) convertView.findViewById(R.id.text);
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                convertView.setTag(holder);
            }else{
                // Get the ViewHolder back to get fast access to the TextView
                // and the ImageView.
                holder = (ViewHolder) convertView.getTag();
            }
            // Bind the data efficiently with the holder.
            holder.text.setText(DATA[position]);
            holder.icon.setImageBitmap((position &1) ==1? mIcon1 : mIcon2);
            returnconvertView;
        }
        staticclassViewHolder {
            TextView text;
            ImageView icon;
        }
    }

Android的界面開發模式決定了實現某一種風格的組件存在不少種方法,而若是沒有對它的界面框架有個比較全面的理解的話每每實現起來要走不少彎路,譬如給各item設置背景色。由於在郵件列表中要顯示兩種顏色,已經閱讀過的和未讀的郵件以不一樣的背景色標識。
在item的layout文件裏只能設置一中固定的顏色,這固然不是我想要的。
最直接的思路就是在Adapter的getView中根據position的不一樣來設置不一樣的背景色,可是設置了不一樣顏色後發如今屏幕上選中一行時背景色沒有變化,選中跟沒選中的顏色是同樣的。因而又從新設置selector,但仍然不起做用。
看 來getView中返回的View就是ListView中各行最終顯示界面,因此又想着先在ListView的 OnItemClickListener中記錄當前選中的Item,而後在getView中判斷是否是該行,若是是,就設置爲選中的背景色。可是這種方法 存在很大的問題,第一個問題就是onItemClickListener是在用戶點擊以後調用的,因此背景色的改變也是用戶點完了以後才發生,而正確的應 該是press的一瞬間改變背景色。第二個問題是,再返回到該ListView時須要在代碼裏從新清楚選中行的記錄,不然該行的背景色不會刷新。
最終的解決方法是這樣的:
實現兩個selector文件(正常顯示下有幾種背景色就須要幾個這樣的selector文件)
mail_read_bg.xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0"encoding="utf-8"?>
<item
 android:state_selected="false"
    android:state_pressed="false"
    android:drawable="@color/ltgray"/>
<item android:state_pressed="true"
    android:drawable="@color/red"/>
<item android:state_selected="true"
 android:state_pressed="false"
    android:drawable="@color/red"/>
</selector>
mail_unread_bg.xml
<?xml version="1.0"encoding="utf-8"?>
<item
 android:state_selected="false"
    android:state_pressed="false"
    android:drawable="@color/white"/>
<item android:state_pressed="true"
    android:drawable="@color/red"/>
<item android:state_selected="true"
 android:state_pressed="false"
    android:drawable="@color/red"/>
</selector>

在getView中根據郵件不一樣的狀態設置不一樣的顏色方案
?
1
2
3
4
ifunread
    convertView.setBackgroundResource(R.drawable.mail_unread_bg);
 else
    convertView.setBackgroundResource(R.drawable.mail_read_bg);


本文轉自 http://hi.baidu.com/hbzha/blog/item/4c734f6f7b5853c280cb4a38.html
相關文章
相關標籤/搜索