在imdb中有这样的界面:
画红框的部分其实都是ListView中的条目,不过它们是不同的View。
实现了一个类似的界面效果:
其中日期标题部分视图布局:
<?xml version= 1.0 encoding= utf-8 ?>
<LinearLayout xmlns:android= http://schemas.android.com/apk/res/android
android:orientation= vertical android:layout_width= fill_parent
android:layout_height= 10dip android:background= @drawable/section_background >
<TextView android:id= @+id/section_title
android:layout_width= fill_parent android:layout_height= match_parent />
</LinearLayout>
带图片的条目布局部分:
<?xml version= 1.0 encoding= utf-8 ?>
<LinearLayout xmlns:android= http://schemas.android.com/apk/res/android
android:layout_width= fill_parent android:layout_height= wrap_content
android:orientation= horizontal >
<ImageView android:id= @+id/image android:src= @drawable/p
android:layout_width= wrap_content android:layout_height= wrap_content />
<TextView android:id= @+id/title android:layout_width= wrap_content
android:layout_height= wrap_content />
</LinearLayout>
问题在于,如何在ListView中既有标题条目又有内容条目。
这里用到了设计模式中的Iterator模式。在java代码中示例有Iterator,可以迭代ArrayList,HashSet等不同的数据结构对象。
这里设计了一个类族:
ListElement是接口:
package com.easymorse.listview.customer;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
public interface ListElement {
public int getLayoutId();
public boolean isClickable();
public View getViewForListElement(LayoutInflater layoutInflater,
Context context, View view);
}
其中:
getLayoutId()返回布局的值;
isClickable()返回是否可点击;
getViewForListElement()返回视图对象。
这个接口有两个实现:
SectionListElement,用于实现标题条目;
ContentListElement,用于实现内容条目。
见SectionListElement代码:
package com.easymorse.listview.customer;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class SectionListElement implements ListElement {
private String text;
public void setText(String text) {
this.text = text;
}
@Override
public int getLayoutId() {
return R.layout.section;
}
@Override
public boolean isClickable() {
return false;
}
@Override
public View getViewForListElement(LayoutInflater layoutInflater,
Context context, View view) {
LinearLayout layout = (LinearLayout) layoutInflater.inflate(getLayoutId(), null);
TextView textView=(TextView) layout.findViewById(R.id.section_title);
textView.setText(text);
return layout;
}
}
见ContentListElement代码:
package com.easymorse.listview.customer;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ContentListElement implements ListElement {
private String title;
public void setTitle(String title) {
this.title = title;
}
@Override
public int getLayoutId() {
return R.layout.item;
}
@Override
public View getViewForListElement(LayoutInflater layoutInflater,
Context context, View view) {
LinearLayout layout = (LinearLayout) layoutInflater.inflate(
getLayoutId(), null);
TextView textView = (TextView) layout.findViewById(R.id.title);
textView.setText(title);
return layout;
ListView需要ListAdapter的实现。在这里是直接集成BaseAdapter来实现的。用于交给ListView生成出列表。代码:
package com.easymorse.listview.customer;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class CustomerListAdapter extends BaseAdapter {
private Context context;
protected ArrayList<ListElement> resultList;
private LayoutInflater layoutInflater;
public CustomerListAdapter(Context context) {
super();
this.context = context;
this.layoutInflater = (LayoutInflater) context
.getSystemService( layout_inflater );
this.resultList = new ArrayList<ListElement>();
}
@Override
public int getCount() {
return this.resultList.size();
}
@Override
public Object getItem(int position) {
return this.resultList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
return this.resultList.get(position).getViewForListElement(
layoutInflater, context, view);
}
public void addList(List<ListElement> elements) {
this.resultList.addAll(elements);
}
@Override
public boolean isEnabled(int position) {
return this.resultList.get(position).isClickable();
}
public void addSectionHeaderItem(String text) {
SectionListElement element = new SectionListElement();
element.setText(text);
this.resultList.add(element);
}
}
在Activity中创建CustomerListAdapter以及设置它的代码部分:
CustomerListAdapter adapter = new CustomerListAdapter(this);
adapter.addSectionHeaderItem( 2002-3-1 );
ArrayList<ListElement> elements = new ArrayList<ListElement>();
for (int i = 0; i < 5; i++) {
ContentListElement element = new ContentListElement();
element.setTitle( 哈利波特第 + (i+1) + 集 );
elements.add(element);
}
adapter.addList(elements);
adapter.addSectionHeaderItem( 2002-2-2 );
elements = new ArrayList<ListElement>();
for (int i = 0; i < 3; i++) {
ContentListElement element = new ContentListElement();
element.setTitle( 指环王第 + (i+1) + 集 );
elements.add(element);
}
adapter.addList(elements);
this.setListAdapter(adapter);
这里ListActivity,还需要注意两件事情,Activity要继承ListActivity。另外,在layout中:
http://easymorse.googlecode.com/svn/tags/customer.listview-0.1.0/