我有一个ListView,我想在其中显示来自多个适配器的项目,例如来自不同查询的两个SimpleCursorAdapter
。每个适配器都有自己的布局,不必相同。
我尝试使用以下包装类:
public class MultiListAdapter implements ListAdapter {
private List<ListAdapter> adapters;
private static class PositionResult {
ListAdapter adapter;
int position;
PositionResult(ListAdapter adapter, int position) {
this.adapter = adapter;
this.position = position;
}
}
private PositionResult getInternalPosition(int position) {
int i = 0;
int result = position;
for (ListAdapter adapter: adapters) {
int count = adapter.getCount();
if (result < count) {
return new PositionResult(adapter, result);
}
result -= count;
++i;
}
return null;
}
public MultiListAdapter(List<ListAdapter> adapters) {
this.adapters = adapters;
}
@Override
public int getCount() {
int result = 0;
int i = 0;
for (ListAdapter adapter: adapters) {
int c = adapter.getCount();
result += c;
}
return result;
}
@Override
public Object getItem(int position) {
PositionResult p = getInternalPosition(position);
return p.adapter.getItem(p.position);
}
@Override
public long getItemId(int position) {
PositionResult p = getInternalPosition(position);
return p.adapter.getItemId(p.position);
}
@Override
public int getItemViewType(int position) {
PositionResult p = getInternalPosition(position);
return p.adapter.getItemViewType(p.position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
PositionResult p = getInternalPosition(position);
return p.adapter.getView(p.position, convertView, parent);
}
@Override
public int getViewTypeCount() {
int result = 0;
for (ListAdapter adapter: adapters) {
result += adapter.getViewTypeCount();
}
return result;
}
@Override
public boolean hasStableIds() {
for (ListAdapter adapter: adapters) {
if (!adapter.hasStableIds()) {
return false;
}
}
return true;
}
@Override
public boolean isEmpty() {
for (ListAdapter adapter: adapters) {
if (!adapter.isEmpty()) {
return false;
}
}
return true;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
for (ListAdapter adapter: adapters) {
adapter.registerDataSetObserver(observer);
}
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
for (ListAdapter adapter: adapters) {
adapter.unregisterDataSetObserver(observer);
}
}
@Override
public boolean areAllItemsEnabled() {
for (ListAdapter adapter: adapters) {
if (!adapter.areAllItemsEnabled()) {
return false;
}
}
return true;
}
@Override
public boolean isEnabled(int position) {
PositionResult p = getInternalPosition(position);
return p.adapter.isEnabled(p.position);
}
}
如果每个列表中只有几个元素,则此方法有效。但如果它有更多,我需要滚动,那么列表完全中断,显示混合的元素,当我点击它们时,它们甚至给我不同的位置而不是它们的真实位置。
上面的代码有什么问题?
答案 0 :(得分:1)
问题是getItemViewType()
方法为不同的视图返回相同的值,尽管实际的视图类型不同。这使得系统尝试重用不同类型的视图。
该方法应该如下所示:
private int getMaxViewType() {
int result = 1;
for (ListAdapter adapter: adapters) {
result = Math.max(result, adapter.getViewTypeCount());
}
return result;
}
@Override
public int getItemViewType(int position) {
PositionResult p = getInternalPosition(position);
return p.adapterId*getMaxViewType() + p.adapter.getItemViewType(p.position);
}