Android ListView ArrayAdapter无法正常工作

时间:2015-02-16 21:25:14

标签: java android listview android-listview

我正在尝试使用我自己的自定义和所谓的"小部件"来创建Android ListView。

这是我的Widget父类:

public class Widget {

protected Context context;

protected int layout;
protected int headlineId;
protected int leftButtonId;
protected int rightButtonId;
protected int headlineTextId;
protected View fragment;
protected LayoutInflater inflater;

protected View widgetView;
protected TextView headline;
protected ImageButton leftButton, rightButton;

protected void init() {
    context = fragment.getContext();

    widgetView = inflater.inflate(layout, parentLayout, false);

    headline = (TextView) widgetView.findViewById(headlineId);
    leftButton = (ImageButton) widgetView.findViewById(leftButtonId);
    rightButton = (ImageButton) widgetView.findViewById(rightButtonId);

    headline.setText(headlineTextId);

    leftButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(fragment.getContext(), "[Move]", Toast.LENGTH_SHORT).show();
        }
    });


    rightButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(fragment.getContext(), "[Hide]", Toast.LENGTH_SHORT).show();
        }
    });
}

public View getLayout() {
    return widgetView;
}

public int getLayoutId() {
    return layout;
}

public void setLayout(View layout) {
    this.widgetView = layout;
}

public int getHeadlineTextId() {
    return headlineTextId;
}

public TextView getHeadline() {
    return headline;
}

public void setHeadline(String s) {
    headline.setText(s);
}

public void setHeadline(int resId) {
    setHeadline(context.getString(resId));
}

}

我在我的widget子类的扩展中使用这个类,像这样(提取):

public class NowWidget extends Widget {

private TextView degree;

public NowWidget(View fragment, LayoutInflater inflater) {
    super();
    this.fragment = fragment;
    this.inflater = inflater;

    this.layout = R.layout.widget_now;
    this.headlineId = R.id.widget_now_card_headline;
    this.leftButtonId = R.id.widget_now_card_left_button;
    this.rightButtonId = R.id.widget_now_card_right_button;
    this.headlineTextId = R.string.now;

    init();
}

public void init() {
    super.init();

    degree = (TextView) widgetView.findViewById(R.id.widget_now_degree);
}

public void setDegree(String s) {
    degree.setText(s);
}

}

widget类背后的想法:Everything(包括带有所有数据的视图)保存在这个类中,可以通过getLayout()调用。

在我的片段中,我创建了小部件并用数据填充它们(Getter和Setter)。一开始,我使用普通的LinearLayouts,只是添加了小部件。一切都运转正常。

但现在我必须使用ListViews(性能)并尝试使用以下适配器:

public class WidgetAdapter extends ArrayAdapter<Widget> {

private ArrayList<Widget> widgets;

public WidgetAdapter(Context context, ArrayList<Widget> widgets) {
    super(context, 0, widgets);

    this.widgets = widgets;
}

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

    return getItem(position).getLayout();

}

private static class WidgetHolder {
    public Widget widget;
}

}

我在我的片段中设置了适配器:

    CustomWidgetListView widgetListView = (CustomWidgetListView) fragment.findViewById(R.id.now_list_view);

    ArrayList<Widget> widgetList = new ArrayList<Widget>();

    for (int i = 0; i < 20; i++) {

        NowWidget nowWidget = new NowWidget(fragment, inflater);

        nowWidget.setHeadline("Widget " + i);

        widgetList.add(nowWidget);

    }

    WidgetAdapter adapter = new WidgetAdapter(context, widgetList);
    widgetListView.setAdapter(adapter);

小部件被创建,我可以在ListView中看到它们。这不是我的问题。

但是:小部件的顺序不正确:加载时屏幕外的所有内容都没有创建,并且“#34; old&#34;显示小部件:

我的ListView顶部: Top of my ListView

向下滚动: Scrolled down

我已经注意到(通过记录widgets-ArrayList)ArrayList在滚动时更改。但为什么呢?

我真的不知道为什么会这样。我已经在我的适配器中尝试了很多其他getView方法,但有时ListView中没有小部件,或者它们的顺序仍然错误。

我也试过这个(现在正在工作):

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

    if (convertView == null) {
        Widget widget = getItem(position);
        convertView = widget.getLayout();
    }

    return convertView;
}

我希望有人能帮助我。

谢谢!

1 个答案:

答案 0 :(得分:0)

ListView正在回收您的View,因此不必每次都制作新的getView。如果创建了新视图,则需要逻辑,如果视图不为null,则需要逻辑,但是要回收。

if convertView == null方法中,您可以使用正确的逻辑来制作新视图(convertView)。

现在,如果视图不为空,则必须使{{1}}指向正确的小部件,因为如果它不为空,则它会尝试回收视图,并且在不更改的情况下返回它它给你意想不到的输出。