简体   繁体   中英

getView() in ArrayAdapter not getting called from AsyncTask

In one of my android activity, I've a ListView lvFeedsList . Each row element in the listView will contain 3 textViews - RSSFeedName, publishDate & feedLength

The contents of the feeds is retrived from a HTTPRsponse . I'm fetching this response in an AsyncTask .

So, in the doInBackground() , I've send the HTTPRequest & received & parsed the response & prepared the ArrayList containing 3 above mentioned information.

Then inside the doInBackground() only, I'm creating the customized ArrayAdapter for forming the 3 TextViews in row element. My intetions are to set this adapter on ListView in onPostExecute() .

But, when I run the application, the ListView does not display anything.

I tried to debug & it seems like getView() in the ArrayAdapter class is not getting called. (But I'm not sure if this is the reason).

Here is the code, sorry for the length...it seemed necessary.

Activity Code:

public class GenericFeedsActivity extends Activity{

    private ListView lvFeedsList;
    private ArrayList<FeedsClass> feedList;

    protected void onCreate(Bundle savedInstanceState) {
        ...
        lvFeedsList = (ListView) findViewById(R.id.lvFeedsList);
        lvFeedsList.setOnItemClickListener(this);
        lvFeedsList.setEnabled(false);
        ...
        new AsyncResponseHandler(this).execute();
    }

    class AsyncResponseHandler extends AsyncTask {
        Context context;
        FeedListAdapter adapter;

        public AsyncResponseHandler(Context c) {
            this.context = c;
        }

        @Override
        protected Object doInBackground(Object... params) {
            ...
            /* 
             *  Sending HTTPRequest to a URL & getting list of feeds
             *  Saving this list of feeds in a ArrayList -feedList, containing elements of type FeedsClass (declared above)
             *  Below line parses the HTTPResponse XML & stores various information in feedList.
             */
            feedList = utils.parseRssResponseXML(in);   // Working fine, geeting elements
            adapter = new FeedListAdapter(
                GenericFeedsActivity.this, feedList);
            in.close();
            return null;
        }

        protected void onPostExecute(Object e) {
            // Setting Arrayadapter
            lvFeedsList.setAdapter(adapter);
            lvFeedsList.setEnabled(true);
        }
    }
}

Adapter Code:

public class FeedListAdapter extends ArrayAdapter {

    private Context context;
    private ArrayList<FeedsClass> feedList;

    public FeedListAdapter(Context c, ArrayList<FeedsClass> data) {
        super(c, R.layout.rowlayout);
        this.context = c;
        this.feedList = data;
    }

    class ViewHolder {
        TextView tvFeedName;
        TextView tvFeedPubDate;
        TextView tvFeedLength;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        ViewHolder holder = null;
            if (row == null) {

                LayoutInflater inflator = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflator.inflate(R.layout.rowlayout, null);
                holder = new ViewHolder();

                holder.tvFeedName = (TextView) row.findViewById(R.id.tvFeedName);
                holder.tvFeedPubDate = (TextView) row.findViewById(R.id.tvFeedPubDate);
                holder.tvFeedLength = (TextView) row.findViewById(R.id.tvFeedLength);

                row.setTag(holder);
            } else {
                holder = (ViewHolder) row.getTag();
            }
            // Getting values of feedName, publishDate & feedLength
            String feedName = feedList.get(position).getTitle();
            String feedDate = feedList.get(position).getPublishDate();
            String feedLength = feedList.get(position).getStreamLength();

            holder.tvFeedName.setText(feedName);
            holder.tvFeedPubDate.setText(feedDate);
            holder.tvFeedLength.setText(feedLength);
        }
        return row;
    }
}

The issue is that you are subclassing ArrayAdapter . This doesn't work because ArrayAdapter internally thinks you do not have any elements in your data; it doesn't just magically know to look in the lvFeedsList variable because the data set it uses is internal.

Instead, in your constructor make sure to call this constructor instead:

Adapter code:

public FeedListAdapter(Context c, ArrayList<FeedsClass> data) {
    super(c, R.layout.rowlayout, data); // add 'data'
    this.context = c;
    this.feedList = data;
}

Which will make everything work correctly.

adapter.notifyDataSetChanged()

could help at the end on of AsyncResponseHandler.onPostExecute(). If not - check whether ArrayList which hold data for adapter is empty or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM