I am trying to do an Android ListView with my own, custom and so called "widgets".
This is my Widget parent-class:
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));
}
}
I am using this class in extension with my widget subclasses, like this (extract):
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);
}
}
The idea behind the widget class: Everything (including the view with all data) is saved in this class and can be called via getLayout().
In my fragments, I create the widgets and fill them with data (Getter and Setter). In the beginning, I worked with normal LinearLayouts and just added the widgets to it. Everything was working properly.
But now I have to use ListViews (performance) and tried it with the following Adapter:
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;
}
}
I set the Adapter in my fragment like this:
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);
The widgets get created and I can see them in my ListView. This is not my problem.
BUT: The widgets are not in the right order: everything what is off-screen on loading, is not created and the "old" widgets are shown:
Top of my ListView:
Scrolled down:
I have already noticed (via logging the widgets-ArrayList) that the ArrayList changes on scrolling. But why?
I have really no idea why this happens. I've already tried a lot of other getView-methods in my adapter, but sometimes there were no widgets in the ListView or they were still in the wrong order.
I've also tried this (now working):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
Widget widget = getItem(position);
convertView = widget.getLayout();
}
return convertView;
}
I hope someone of you can help me.
Thanks!