Android:如何重用具有动态项目数和多个布局的列表视图项

时间:2012-12-28 20:12:08

标签: android android-listview

当我尝试在具有多个自定义布局的ListView中重用视图时出现问题。当我改变项目数量时,我得到的错误是将convertView传递给getView方法。详情如下: 我有标题布局,行布局和页脚布局。在标题中,我可以更改行数。 1行示例: 头 ROW1 页脚 当我重用视图时,我得到错误的结果(添加另一行后)。这是因为之前创建的页脚视图是为position = 2传递的,因为它不是null我不会重新创建它: 头 ROW1 页脚 页脚

而非预期: 头 ROW1 2行 页脚

我做错了什么?或者是设计,我应该重新创建视图而不是重用它们? 这是我的代码:

public class NewProgramAdapter extends BBBaseAdapter {

public static int TYPE_HEADER = 1;
public static int TYPE_FORM = 2;
public static int TYPE_FOOTER = 3;

protected String mDays;
protected String mProgramId;
protected int currentDay = 0;
protected int numberOfExercises = 1;
protected JSONArray items = new JSONArray();

public NewProgramAdapter(Activity a) {
    super(a);
    // TODO Auto-generated constructor stub
}

@Override
public int getCount() {
    return numberOfExercises + 2; // header and footer
}

@Override
public Object getItem(int position) {
    return position;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (position > 0 && position < getCount() - 1) {
        return getFormView(position, convertView, parent);
    } else if (position == 0) {
        return getHeaderView(position, convertView, parent);
    } else {
        return getFooterView(position, convertView, parent);
    }
}

private View getFooterView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater inflater = mA.getLayoutInflater();
        v = inflater.inflate(R.layout.new_exercise_footer, null);
    }
    return v;
}

private View getHeaderView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater inflater = mA.getLayoutInflater();
        v = inflater.inflate(R.layout.new_exercise_header, null);
        Spinner sp = (Spinner) v.findViewById(R.id.spinnerExercises);
        sp.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView,
                    View selectedItemView, int position, long id) {
                int n = position + 1;
                setNumberOfExercises(n);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                // your code here
            }

        });
    }
    return v;
}

private View getFormView(int position, View convertView, ViewGroup parent) {

    View v = convertView;
    if (v == null) {
        LayoutInflater inflater = mA.getLayoutInflater();
        v = inflater.inflate(R.layout.new_exercise_form, null);
    }
    return v;
}

@Override
public int getItemViewType(int position) {
    if (position > 0 && position < getCount() - 1) {
        return TYPE_FORM;
    } else if (position == 0) {
        return TYPE_HEADER;
    } else {
        return TYPE_FOOTER;
    }
}

@Override
public void updateEntries(Object data) {
    items = (JSONArray) data;
    notifyDataSetChanged();
}

public void next() {
    currentDay++;
    notifyDataSetChanged();
}

public void setNumberOfExercises(int n) {
    numberOfExercises = n;
    notifyDataSetChanged();
}

public void setDays(String string) {
    mDays = string;
}

public void setProgramId(String string) {
    mProgramId = string;
}

}

1 个答案:

答案 0 :(得分:3)

看起来您忘记覆盖getViewTypeCount(),它告诉适配器使用多个行布局。

但是,如果您只需要页眉,页脚和行布局,则应使用ListView#addHeaderView()ListView#addFooterView()。不要试图控制页眉和页脚是你的适配器,ListView已经为你做了。