自定义列表适配器无意重新排列

时间:2013-05-20 19:43:56

标签: android android-arrayadapter

我写了一个要在我的ListActivity中使用的ArrayAdapter,但出于某种原因,当我向下滚动然后向上滚动时,我的列表的顺序正在重新排列,我不明白为什么。加载项目时项目的初始顺序是正确的。问题是当我向下滚动并从屏幕上获得一些顶部项目然后向上滚动到它们时,它们是不同的。我的ArrayList没有从外部源更改。谁能看到我哪里出错了?

public class List3ItemAdapter extends ArrayAdapter {

    private final static String DBG = "List3ItemAdapter";
    private Activity activity;
    private ArrayList<GenericListItem> listItems;
    private static LayoutInflater inflater;
    private ArrayList<View> listViews;

    public List3ItemAdapter(Activity activity, ArrayList<GenericListItem> listItems) {

        super(activity, android.R.layout.simple_list_item_1);

        this.listItems = listItems;

        this.activity = activity;

        this.listViews = new ArrayList<View>();



        inflater = (LayoutInflater) activity.getSystemService(activity.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        return listItems.size();
    }

    public Object getItem(int position) {
        return listItems.get(position);
    }

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

    public View getViewByPos(int pos) {
        return listViews.get(pos);
    }

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

        //   Log.d(DBG, "current position is: " + position);
        View vi = convertView;

        GenericListItem listItem = listItems.get(position);

        ArrayList<String> values = listItem.getDisplayValues();


        if (vi == null) {

            if (listItem.getIsSection()) {
                vi = inflater.inflate(R.layout.list_section, null);
            } else {
                vi = inflater.inflate(R.layout.list_3itemrow, null);
            }

            listViews.add(vi);
        }

        if (listItem.getIsSection()) {

            TextView sectionTitle = (TextView) vi.findViewById(R.id.sectionTitle);
            sectionTitle.setText(values.get(0));

        } else {

            TextView title = (TextView) vi.findViewById(R.id.primaryTitle);
            TextView secondary = (TextView) vi.findViewById(R.id.secondaryTitle);
            TextView rightData = (TextView) vi.findViewById(R.id.rightData);

            secondary.setVisibility(View.GONE);
            rightData.setVisibility(View.GONE);

            Integer count = 0;

            for (String str : values) {
                count++;

                if (count == 1) {

                    title.setText(str);

                } else if (count == 2) {

                    secondary.setText(str);
                    secondary.setVisibility(View.VISIBLE);

                } else if (count == 3) {

                    rightData.setText(str);
                    rightData.setVisibility(View.VISIBLE);
                }
            }

        }

        return vi;
    }
}

1 个答案:

答案 0 :(得分:2)

  1. 不需要ArrayAdapter,因为您提供自己的getView(),并且自己正在处理getItem()。 BaseAdapter应该完成这项工作。

  2. 如果您想要两种视图,请使用getItemViewType(int position)getViewTypeCount()。第二个应返回两个,第一个应返回0表示标题,1表示内容。这样,您将使ListView能够正确地回收视图。

  3. getView()中使用getItemViewType(int position)检查视图的类型,并对正确的视图(标题或内容)进行充气或重用(如果提供)。根据视图类型,填写内容。

  4. 充气器不应该是静止的。适配器绑定到活动,并且可能不应该保持对连接到它的任何东西的静态引用。除非你有正当理由,否则不要为这些东西使用静态变量:)此外,还有一个有用的快捷方式来获取LayoutInflater:LayoutInflater.from(context)