【问题标题】:ListView not refreshed until user interactionListView 在用户交互之前不会刷新
【发布时间】:2014-01-13 22:08:39
【问题描述】:

我有一个 ListView 和一个自定义适配器。当用户从微调器更改排序类型时,我想用新项目重绘列表。问题是 ListView 只有在我在设备上与之交互后才会重新绘制(例如开始滚动)。

if (update) {
                mOfferList = (ArrayList<PositionSearchItem>) psr
                            .getPositionSearchItem();

                mAdapter.clear();
                mAdapter.addAll(mOfferList);
                mAdapter.notifydataSetChanged()
                mList.invalidate();
                mList.invalidateViews();

}

我还尝试将我的适配器的新实例完全重置到列表中,它给出了相同的结果,只是列表首先变为空白并出现在用户交互中。

我正在使用 HoloEveryWhere,也许这是一个重要信息。

编辑:这里还有一些代码

@EFragment(R.layout.list_fragment_results)
public class ResultsListFragment extends Fragment {

    @ViewById(R.id.search_results_list)
    ListView mList;
    @ViewById(R.id.search_result_list_spinner)
    Spinner mSpinner;
    MainActivity mActivity;
    private String mTypedText;
    private List<String> mSortType;
    private ResultsListFragment mFrag;
    private Bundle mOffersPageBundle;
    private SearchResultsListAdapter mAdapter;
    private ArrayList<PositionSearchItem> mOfferList;

    @AfterViews
    public void afterViews() {
        mFrag = this;
        mActivity = (MainActivity) getActivity();
        mSortType = new ArrayList<String>();
        mSortType.add(SearchResultSortType.SCORE_DESCENDING);
        mOfferList = new ArrayList<PositionSearchItem>();

        mOffersPageBundle = getArguments();
        PositionSearchResponse psr = mOffersPageBundle.getParcelable("offers");
        mTypedText = mOffersPageBundle.getString("typedText");

        mOfferList = (ArrayList<PositionSearchItem>) psr.getPositionSearchItem();

        mAdapter = new SearchResultsListAdapter(this,
                android.R.layout.simple_list_item_1, mOfferList, mTypedText,
                mSortType, mActivity.getLat(), mActivity.getLon());
        mList.setAdapter(mAdapter);

        this.setListeners();
    }

    private void setListeners() {

        mSpinner.setOnItemSelectedListener(new org.holoeverywhere.widget.AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(
                    org.holoeverywhere.widget.AdapterView<?> parent, View view,
                    int pos, long id) {
                Boolean update = false;
                PositionSearchResponse psr = null;
                switch (pos) {
                case 0:
                    if (mSortType.get(0) != SearchResultSortType.SCORE_DESCENDING) {
                        mSortType.clear();
                        mSortType.add(SearchResultSortType.SCORE_DESCENDING);
                        psr = processSearch(mTypedText, mSortType, 0, mActivity);
                        update = true;
                    }
                    break;
                case 1:
                    if (mSortType.get(0) != SearchResultSortType.DATE) {
                        mSortType.clear();
                        mSortType.add(SearchResultSortType.DATE);
                        psr = processSearch(mTypedText, mSortType, 0, mActivity);
                        update = true;
                    }
                    break;

                default:
                    break;
                }

                if (update) {
                    mOffersPageBundle.putParcelable("offers", psr);
                    mOfferList = (ArrayList<PositionSearchItem>) psr
                            .getPositionSearchItem();

                    mAdapter.mIdMap.clear();
                    for (int i = 0; i < mOfferList.size(); ++i) {
                        mAdapter.mIdMap.put(mOfferList.get(i), i);
                    }

                    mOfferList = (ArrayList<PositionSearchItem>) psr
                            .getPositionSearchItem();

                    mAdapter.clear();
                    mAdapter.addAll(mOfferList);
                    mAdapter.notifydataSetChanged()
                    mList.invalidate();
                    mList.invalidateViews();
                }
            }

            @Override
            public void onNothingSelected(
                    org.holoeverywhere.widget.AdapterView<?> parent) {
                // TODO Auto-generated method stub

            }

        });
    }
}

编辑:自定义适配器的 getView 方法

@Override
public View getView(int pos, View convertView, ViewGroup parent) {
    this.v = convertView;
    LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);
    PositionSearchItem psr = getItem(pos);

    v = vi.inflate(R.layout.result_list_item, parent, false);
    v.setTag(pos);
    // Inject text into view
    ((TextView) v.findViewById(R.id.result_title_textview))
            .setText(getItem(pos).getTitle());

    // Disable hardware acceleration for the view (it brakes dotted lines on
    // some devices)
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    // reload list if scrolled to bottom
    int page = 0;
    if (pos > mLastViewed && pos == getCount() - 1) {
        mLastViewed = pos;
        ResultsListFragment frag = new ResultsListFragment_();
        PositionSearchResponse newSearch = frag.processSearch(mTypedText, mSortType, mPage,
                mActivity);
        mPage = mPage + 12;

        if(newSearch != null && newSearch.getPositionSearchItem() != null && newSearch.getPositionSearchItem().size() > 0){
            for (int i = 0; i < newSearch.getPositionSearchItem().size(); ++i) {
                mIdMap.put(newSearch.getPositionSearchItem().get(i), i);
            }
            this.addAll(newSearch.getPositionSearchItem());
        }

    }
    return v;
}

【问题讨论】:

  • 使用mAdapter.NotifyDataSetChanged();
  • 对不起,我刚刚在我的帖子中忘记了。我实际上正在使用它。
  • 好的,然后再发布代码,比如从你调用它的地方,以及何时发生更新
  • 您可以在 Spinner ItemSelected 上更新它,只需检查我的答案,我希望它对您有用..

标签: android listview notifydatasetchanged holoeverywhere


【解决方案1】:

使用

if (update) {

mAdapter.NotifyDataSetChanged();
}

【讨论】:

    【解决方案2】:

    这可能会解决您的问题。

    尝试再次设置adatpter。将以下代码放在您编写代码以更新列表视图的所有位置

    mAdapter =  new YourAdapter();
    mList.setAdapet(mAdapter)
    

    【讨论】:

    • 我也试过这个。它具有相同的行为,只是它在用户交互之前给出了一个空白列表。
    • 你是否在列表适配器中编写了任何动画代码,只是问我在加载带有条目动画的列表时遇到了同样的问题..?
    • 你能在帖子中添加getview功能吗?
    • 不,我没有设置任何动画。我已经添加了 getView 方法。
    【解决方案3】:

    我希望你已经使用适配器和模型创建了自定义列表视图。

    现在,当您需要动态更新列表视图时,您需要清除之前创建的列表视图。然后在您需要获取所有新值并在自定义列表视图中更新相同的值之后。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      • 2011-10-07
      • 2012-11-29
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多