首先声明下,这是本人自己使用的做法,可能并不适合每个人,但是具有参考意义,分享给大家,不足的地方希望有人能提出来。
ListView在做应用的时候是经常被使用到的。一般开发应用程序的时候,我们会先做界面。这个时候,遇到ListView,我们会先模拟一些数据,而且,每个ListView通常都有类型的行为,比如,ListView的每个Item的点击效果,Item之间的横线,等等,而通常我们不会去使用自带的list item 的布局,而是自己去写一个布局,然后在自定义的Adapter中去inflate它。在多个地方都使用到这些特性,那么我们就可以把这些特性放到父类中来处理。而对于界面中共同的元素我们会放到style中去处理。
先看MainAdapter.java:
public class MainAdapter extends BaseCompatableAdapter<Map<String, String>> { public MainAdapter(Context context, List<Map<String, String>> data) { super(context, data); } class ViewHolder { ImageView ivPic; TextView tvName; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final ViewHolder viewHolder; if (convertView == null) { convertView = super.layoutInflater .inflate(R.layout.list_item, null); viewHolder = new ViewHolder(); viewHolder.ivPic = (ImageView) convertView .findViewById(R.id.iv_pic); viewHolder.tvName = (TextView) convertView .findViewById(R.id.tv_name); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } //TODO 接下去对数据进行绑定... return convertView; } }
这里面做的事情非常简单,因为我把部分代码移到了父类BaseCompatableAdapter中,
下面看父类
BaseCompatableAdapter.java:
public abstract class BaseCompatableAdapter<T> extends BaseAdapter { protected Context context; private List<T> data; protected LayoutInflater layoutInflater; public BaseCompatableAdapter(Context context, List<T> data) { this.context = context; this.data = data; layoutInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { // TODO Auto-generated method stub if (data == null) return 0; return data.size(); } @Override public T getItem(int position) { // TODO Auto-generated method stub return data.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } }
覆写过BaseAdapter的同学应该可以知道,实际上就是把BaseAdapter的部分方法在这里面覆写了。以后你的其他的Adapter都继承自这个Adapter,那么可以省下不少的代码量。
最后看主界面:
MainActivity.java:
public class MainActivity extends Activity { private ListView lvData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvData = (ListView)findViewById(R.id.lv_data); List<Map<String, String>> dataList = new ArrayList<Map<String, String>>(); Map<String, String> map; for(int i = 0; i < 50; i++){//模拟数据量,当并没有加入真实的数据源 map = new HashMap<String, String>(); dataList.add(map); } lvData.setAdapter(new MainAdapter(this, dataList)); } }
上面是关于代码中如何较为简洁的处理ListView和Adapter,下面则是设置ListView的界面
用一个style来设置每个ListView公用的地方,如下:
res/values/styles.xml:
<resources>
<style name="listview_style" parent="@android:style/Widget.ListView">
<!-- <item name="android:listSelector">@drawable/list_item_bg_selecter</item> -->
<item name="android:divider">@drawable/line</item><!-- @drawable/list_item_line -->
<item name="android:cacheColorHint">@null</item>
</style>
</resources>
这里面设置了divider,即Item之间的横线,cacheColor设置为null,listSelector设置list item点击下去的效果。因为我将selector写到了list item里面去了,所以这里就注释掉了,实际上这里最好可以写入一个默认的selector,这样所有的listview的item都默认有一个selector样式!在一些情况下,比如List item中嵌套着一个ViewStub,那么这个时候你设置的listSelector会失效,这个时候,只能够在List item中设置背景selector,而且要注意,如果是ViewStub这种情况的话,不能将list item最外层的layout设置背景selector,而是要在除了ViewStub,在剩下的那个控件里面设置selector,即点击会显示或隐藏ViewStub的那个控件。
你的listview可以这样引用style:
<ListView android:id="@+id/lv_data" android:layout_width="fill_parent" android:layout_height="fill_parent" style="@style/listview_style" />
下面我们看看list Item
res/layout/list_item.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/list_item_bg_selecter" > <ImageView android:id="@+id/iv_pic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:src="@drawable/ic_launcher" android:layout_margin="5dip" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="10dip" android:layout_toRightOf="@+id/iv_pic" android:text="张三" /> </RelativeLayout>
注意在这里面我设置了android:background="@drawable/list_item_bg_selecter"这是关键,这里决定了ListView的每个Item的点击效果:但是这里也可以没有selector,如果没有的话,就会调用style中定义的selector,如果style中你没有设置,那么就会调用默认的selector(按下去橘黄色的那种效果)。
res/drawable/list_item_bg_selector.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/list_item_bg_sel" android:state_pressed="true"/> <item android:drawable="@drawable/list_item_bg_sel" android:state_focused="true"/> <item android:drawable="@drawable/list_item_bg_sel" android:state_selected="true"/> <item android:drawable="@drawable/list_item_bg_nor"/> </selector>
这个selector中用到的图片可以是普通图片,也可以是自己画的图片,比如:
res/drawable/list_item_bg_sel.xml:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#efece7" /> </shape>
list_item_bg_nor.xml也是一样,只不过设置不同的颜色。
当然横线你也可以自己画,比如:
res/drawable/line.xml:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <stroke android:width="1dp" /> <size android:height="3dp" /> <solid android:color="#efece7" /> </shape>
下面附上效果图和项目结构图:
项目地址: