我有一个ListView,我在其中显示日期。通过使用Spinner,我可以选择要显示的天数(如果列表太长,那么我可以滚动它)。
当我看到30天,并且位于列表的底部时,如果我与微调器一起玩并选择看15天,然后30天,然后15天,我最终会出现重复或错误的元素。
我已经阅读了很多相关内容,应用了所有建议:
无效
invalidateViews
notifyDataSetInvalidated
notifyDataSetChanged
refreshDrawableState
使用Handler来运行这些调用
但没有解决我的问题。
我正在使用以下代码:
=== CustomAdapter ===
public class CustomAdapter extends BaseAdapter {
private List<ViewHolder> viewHolders;
@Inject
public CustomAdapter(@Assisted List<ViewHolder> viewHolders) {
this.viewHolders = viewHolders;
}
@Override
public int getCount() {
return viewHolders.size();
}
@Override
public Object getItem(int i) {
return viewHolders.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return viewHolders.get(i).getView(view);
}
}
=== ListViewHolder ===
public class ListViewHolder extends ViewHolder {
@Override
public View getView(View view) {
Holder holder;
if (view == null) {
view = LayoutInflater.from(contextProvider.get()).inflate(R.layout.entry, null);
holder = new Holder();
holder.text = (TextView) view.findViewById(R.id.textView);
view.setTag(viewStructure);
} else {
holder = (Holder) view.getTag();
}
holder.text.setText(/* date */);
return view;
}
}
=== ListFragment ===
public class ListFragment extends RoboFragment {
private CustomAdapter customAdapter = null;
private List<ViewHolder> viewHolders = new ArrayList<ViewHolder>();
private ListView listView;
private Handler handler = new Handler();
@Inject
private ListFragment(AdapterFactory adapterFactory) {
customAdapter = adapterFactory.createAdapter(viewHolders);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.list, container, false);
listView = (ListView) view.findViewById(R.id.listView);
listView.setAdapter(customAdapter);
return view;
}
public void setContentRange(List<ViewHolder> viewHolders, int range) {
update(viewHolders.subList(0, range));
}
private void update(List<ViewHolder> content) {
viewHolders.clear();
viewHolders.addAll(content);
if (customAdapter != null) {
handler.post(new Runnable() {
@Override
public void run() {
customAdapter.notifyDataSetChanged();
//customAdapter.notifyDataSetInvalidated();
if (listView != null) {
listView.invalidateViews();
// listView.requestLayout();
// listView.refreshDrawableState();
}
}
});
}
}
}
有什么建议吗?提前谢谢。
抱歉,无法发布图片,信誉不足......
编辑:
添加了图片链接
ListViewHolder的代码实际上是这样的。我简化它发布在这里,但也许它很重要:
公共类ListViewHolder扩展了ViewHolder {
@Inject
private ListViewHolder(Holder holder) { // Guice will create the holder
super(holder);
}
@Override
public View getView(View view) {
Holder holder;
if (view == null) {
view = LayoutInflater.from(contextProvider.get()).inflate(R.layout.entry, null);
holder = getHolder(); // getHolder is defined in ViewHolder, and returns the object created in the constructor
holder.text = (TextView) view.findViewById(R.id.textView1);
view.setTag(viewStructure);
} else {
holder = (DualTextViewStructure) view.getTag();
}
holder.text.setText(/* Date */);
return view;
}
}
答案 0 :(得分:0)
事实证明,在构造函数中使用Guice创建的Holder是个问题。 如果我使用Provider,那么列表就会按预期运行
public class ListViewHolder extends ViewHolder {
@Override
public View getView(View view) {
Holder holder;
if (view == null) {
view = LayoutInflater.from(contextProvider.get()).inflate(R.layout.entry, null);
// getHolder looks like this:
// @Inject
// private Provider<Holder> holderProvider;
// public Holder getHolder() {
// holderProvider.get();
// }
holder = getHolder();
holder.text = (TextView) view.findViewById(R.id.textView1);
view.setTag(viewStructure);
} else {
holder = (DualTextViewStructure) view.getTag();
}
holder.text.setText(/* Date */);
return view;
}
}