Android ListView选择要显示的项目数导致洗牌项目

时间:2013-10-13 16:53:32

标签: java android listview android-listview

我有一个ListView,我在其中显示日期。通过使用Spinner,我可以选择要显示的天数(如果列表太长,那么我可以滚动它)。

enter image description here

当我看到30天,并且位于列表的底部时,如果我与微调器一起玩并选择看15天,然后30天,然后15天,我最终会出现重复或错误的元素。

enter image description here

我已经阅读了很多相关内容,应用了所有建议:

  • 无效

  • 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;
    }
    

    }

1 个答案:

答案 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;
    }
}