自定义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
相关文章
相关标签/搜索