سؤال

I have an application in the market with a bug which I can not seem to solve. Today I have tracked it down to the following method.

public void updateDealList(ArrayList<Deal> deals) {
    // first call or showing bookmakrs (also gets called other times when adapter is null)
    if (dealListAdapter == null || showingBookmarks || !dealListAdapter.moreDealsToDownload()) { 
        dealListAdapter = new EndlessDealListAdapter(getActivity(),
                R.layout.deal_list_item, deals);
        setListAdapter(dealListAdapter);
        listView = getListView();
        if (getActivity().findViewById(R.id.right_fragment_container)!=null){ // if tablet
            listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            listView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT);
        }
        showingBookmarks=false;
        Log.d("UPDATE_DEAL_LIST", "Notified list  created new" + dealListAdapter.getCount());
        return; //PROBLEM OCCURS WHEN APP COMES IN HERE AFTER RESUMING
    }
    dealListAdapter.getDealListAdapter().clear();
    for (Deal d: deals){
        dealListAdapter.getDealListAdapter().add(d);
        Log.d("UPDATE_DEAL_LIST", "added " + d.title);
    }
    dealListAdapter.notifyDataSetChanged();
    Log.d("UPDATE_DEAL_LIST", "Notified list " + dealListAdapter.getCount());
}

This method is passed an arraylist of deal objects which are pulled down from the internet. When the application is first opened data is pulled from the internet and the above method is called which creates a new adapter which is set for the ListFragment. This method is also called when the user requests more deals.

The problem I am having is that the list sometimes thinks its empty dispite the adapter containing deals. This seems to occur when a use resume the application when their device is low on memory (I presume part of the application has been removed from ram). This method is called and the dealListAdapter is null so a new one is created and deals are added. Despite this happening the list remains empty and the user has to force close the app to get it working again.

The line below shows tat when the method is called it enters the if and 21 deals are added to the adapter. Unfortunately the list is empty to the user.

05-23 01:52:32.879: D/UPDATE_DEAL_LIST(3478): Notified list  created new21
هل كانت مفيدة؟

المحلول

One idea (pretty long shot :)

If the app itself wasn't killed, just the activity, the system tries to recreate the activity's last state, calling the onRestoreInstanceState(). This method will not be called if the app was killed - so this is one of the big differences between the two.

The ListActivity overrides the onRestoreInstanceState(). It ensures, that the List exists, before it goes on. If the list does not exist, it inflates it from the default place.

If you're setting the contentView in the onResume() try to move it to onCreate(), that may solve the problem.

I can help more, if I see the activty's code.

نصائح أخرى

I really don't know if this is going to help or not but this following method is supposed to resize your list based on its children. I don't understand why sometimes notifyDataSetChanged() does not work, the list simply does not change, but using this instead has solved my problem.

    public static class Utility {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }


        int totalHeight = 0;
        int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        int newHeight = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        if (newHeight >= 100)
            params.height = newHeight;  
        else 
            params.height = 100;
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
}

Hope it helps!

You can try one or more of the following options

  • Try calling setListShown(false) just before setting the list adapter.

  • Otherwise, do
    setListShown(false);
    setListAdapter(null);

  • Otherwise, do requestLayout()

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top