Another Challenge Solution - Custom Adapter


#1

I wasn’t up to speed on the Scroll Lisyener, so I took another route.

I created a custom adapter class, and when getitem was invoked with a position within 20 of the size of the mItems array, I kicked off FetchItemsTask. I too used a page input parm to fetch items, and used a mFetchInProgress variable to keep from initiating the Fetchr excess times.

 ArrayAdapter<GalleryItem> mGalleryAdapter;
...
		@Override
		protected void onPostExecute(ArrayList<GalleryItem> items) {
			Log.d(TAG, "onPostExecute called");
			// if mitems already exists we want to append this result to the array not just replace
			if (mItems == null) {
				mItems = items;				
			} else {
				mItems.addAll(items);
			}

			setupAdapter();
			mFetchInProgress = false;
			mPagesFetched++;
		}
...
	void setupAdapter() {
		if (getActivity() == null || mGridView == null) return;
		
		if (mItems != null) {
	        if (mGridView.getAdapter() == null) {
	        	mGalleryAdapter = new GalleryItemAdapter(mItems);
	        	mGridView.setAdapter(mGalleryAdapter);        
	         }   
	         else {
	        	mGalleryAdapter.notifyDataSetChanged();
	         }
		} else {
			mGridView.setAdapter(null);
		}
	}
	
	private class GalleryItemAdapter extends ArrayAdapter<GalleryItem> {
		public GalleryItemAdapter(ArrayList<GalleryItem> items) {
			super(getActivity(), 0, items);
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			//	Do the default
			if (convertView == null) {
				convertView = getActivity().getLayoutInflater().inflate(android.R.layout.simple_gallery_item, parent, false);
			}
			
			GalleryItem item = getItem(position);
			Log.d(TAG, "getView: position= " + position);
			
			if (position > mItems.size()-20 && !mFetchInProgress) {
				Log.d(TAG, "getView: near end of list get another page");
				mFetchInProgress = true;
				
				// Initiate additional page fetch, on completion add to model notify adapter of update
				new FetchItemsTask().execute(mPagesFetched+1);				
			}
			
			TextView textView = (TextView)convertView.findViewById(android.R.id.text1);
			textView.setText(item.getCaption());
			
			return convertView;
		}
		
	}

One problem that would likely require a container class for the entire Gallery was I wanted to return the # available pages info to the main thread - so once you got the last possible page (10th) in the Flickr dataset, you would not ask for more. To return this required the fetcher to return more than just an array of items, but to also fetch and return the first item with XML label “pages” etc. Since in this example the Fetchr thread did not persist across invocations you could not maintain this type of state there - you could though with a persistent thread as in the subsequent chapter and use the Handler/Message interface.