Browse Reddit with AeroGear Part 2 paging.

Posted By Hoyt Summers Pittman

In December, I described a demonstration of using Aerogear to browse Reddit (link). With the release of Aerogear Android M2, I wanted to take the time to update the demo with the new paging features.

Paging introduced several new interfaces: PagedList, PageResultExtractor, and ParameterProvider as well as PageConfig and default implementations for the new interfaces.

Adding the paging code to the Reddit application was very straight forward.

First let’s look at a response from Reddit:

{
    "data": {
        "after": "t3_17i1lt",
        "before": null,
        "children": [
            {
                "data": {
	     /*snip*/
   }
            }
        ],
        "modhash": ""
    },
    "kind": "Listing"
}

“data.before” and “data.after” are information about the paging state. By default, Aeorgear can support WebLink headers or headers and body parameters which are URIs. Since Reddit uses neither, we need to implement a PageResultExtractor to consume this into AeroGear. This class will parse the data from HeaderAndBody into something usable by the framework.

public class PageConsumer implements PageResultExtractor<PageConfig>{

    public ReadFilter getNextFilter(HeaderAndBody result, PageConfig config) {
        ReadFilter filter = new ReadFilter();
        JsonParser parser =new JsonParser();
        JsonElement element = parser.parse(new String(result.getBody()));
        String next = getFromJSON(element, config.getNextIdentifier());
        if (next != null) {
        	filter.setLinkUri(URI.create("?count=25&after=" + next));
        }
        return filter;
    }

    public ReadFilter getPreviousFilter(HeaderAndBody result, PageConfig config) {
        ReadFilter filter = new ReadFilter();
        JsonParser parser =new JsonParser();
        JsonElement element = parser.parse(new String(result.getBody()));
        String previous = getFromJSON(element, config.getPreviousIdentifier());
        if (previous != null) {
        	filter.setLinkUri(URI.create("?count=26&before=" + previous));
        }
        return filter;
    }

    private String getFromJSON(JsonElement element, String nextIdentifier) {
        String[] identifiers = nextIdentifier.split("\\.");
        for( String identifier:identifiers) {
            element = element.getAsJsonObject().get(identifier);
        }
        if (element.isJsonNull()) {
        	return null;
        }

        return element.getAsString();
    }

}

Now that we can handle Reddit’s responses, we can create a PageConfig object and pass it to our PipeConfig.

//In StoryListApplication.java
     PageConfig pageConfig = new PageConfig();
     pageConfig.setLimitValue(25);
     pageConfig.setMetadataLocation(PageConfig.MetadataLocations.BODY);
     pageConfig.setNextIdentifier("data.after");
     pageConfig.setPreviousIdentifier("data.before");
     pageConfig.setPageHeaderParser(new PageConsumer());

     config.setPageConfig(pageConfig);//config is an instance of PipeConfig

When you have a PageConfig object, Aerogear will wrap the List result from a “read” operation in a PagedList. In StoryList we have created two new fields, a Callback readCallback and a PagedList listings. The callback will assign the result to “listings” and update the UI.

private PagedList<Listing> listings;

private final Callback<List<Listing>> readCallback = new Callback<List<Listing>>() {

	public void onSuccess(List<Listing> data) {
		listings = (PagedList<Listing>) data;
		setListAdapter(new ArrayAdapter<T3>(getActivity(),
                android.R.layout.simple_list_item_activated_1,
                android.R.id.text1,
                data.get(0).getData().getChildren()));
	}

	public void onFailure(Exception e) {
		Log.d("Reddt", "failure", e);
		if (e instanceof HttpException) {
			HttpException httpException = (HttpException) e;
			Log.d("Reddit", new String(httpException.getData()));
		}
	}
};

And now we add methods which call the “next” and “previous” methods on listings.

public void next() {
    listings.next(readCallback);
  }

  public void previous() {
    listings.previous(readCallback);
  }

And now AGReddit can page results. The full code can be found on the GitHub page for AGReddit.

Jan 30th, 2013

One Comment to 'Browse Reddit with AeroGear Part 2 paging.'

Subscribe to comments with RSS or TrackBack to 'Browse Reddit with AeroGear Part 2 paging.'.

:: Trackbacks/Pingbacks ::

  1. Pingback by Aerogear Android M2 | Saga Blog - on January 30th, 2013 at 6:21 pm

Leave a Reply