360AnDev Recap

360AnDev '16 badge and swag

Heading to the Mile-High City

I love going to conferences. I think they are a great way to get out of the office, to stay current on trends in related fields, and to meet/interact with peers. Because of these beliefs, I like to attend at least one conference in every year. After attending AnDevCon Boston last year, I had been targeting DroidCon New York as my conference of choice for 2016.

This past spring, however, I came across a new conference (360AnDev) being held this year in Denver. Initially, it caught my eye because Colorado seemed a bit more accessible to me coming from the west coast. After following the conference website and twitter for a while, I was sold on the potential of 360AnDev to be a terrific event.

Nate Ebel on Twitter

Speaker lineup for @360andev is looking good!

No Title

No Description

“The combination of talented/high-profile speakers, and a schedule packed with interesting talks really sold the event for me”

The combination of talented/high-profile speakers, and a schedule packed with interesting talks really sold the event for me, and I started making my plans to attend. I even convinced some co-workers that this should be the go-to event for the year.

Continue reading

My year with Udacity’s Android Nanodegree

Motivations and Starting Out

A little over a year ago, I had never heard of Udacity and had zero experience with MOOCs. I was a relatively new developer, having only completed my graduate work a year prior. I was eager to improve my skills both with the Android platform and as a software engineer in general.

Then, while live-streaming the Google I/O 2015 keynote I saw an announcement about this thing called a Nanodegree program as a means of learning about Android development using a curriculum and courses developed in conjunction with Google. I was immediately intrigued. It seemed like the perfect opportunity to level-up my skill-set, and I registered for a free trial that same week.

Continue reading

Implementing a Collapsing Toolbar

Implementing Material Designs

With the continuing adoption of Material Design across Android apps, I think there is a bit of a divide between these beautiful/functional designs that are being produced, and the technical knowledge of actually implementing those designs. This gap between design and implementation was recently narrowed with the release of the Design Support Library. There is now an extremely useful set of widgets specifically to make the implementation of Material Design easier on the Android platform.

CollapsingToolbarLayout

I recently spent some time exploring one of these new widgets: the CollapsingToolbarLayout, and wanted share some of what I discovered in implementing an expanded height, collapsing toolbar. The objective of this demo is to simply create an extended height AppBar that contains a title and animates to a standard AppBar height in response to a user scrolling action.

Setup

First off, make sure you have the required dependencies: - `compile 'com.android.support:appcompat-v7:23.0.1` - `compile 'com.android.support:design:23.0.1` Next, ensure you have a new project containing a single `AppCompatActivity`. The code for this activity should look something like this to start:
 public class MainActivity extends AppCompatActivity {  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
   }  
 }  

Create the root layout

For this simple implementation, all the magic takes place within `activity_main.xml`.

First off, update the root element of the layout to be a `CoordinatorLayout`, and make sure to fully qualify the `CoordinatorLayout` class name since it comes from a support library. This will save you from wonderful "Class not found" errors when you deploy and run your app.

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   xmlns:app="http://schemas.android.com/apk/res-auto"  
   tools:context=".MainActivity">  
   <!--AppBarLayout will go here-->  
   <!--Scrolling content will go here-->  
 </android.support.design.widget.CoordinatorLayout>  

Setup the scrolling content

Now it's time to setup the scrolling content. This is the layout that the user will interact with that will cause the toolbar to collapse and expand.

This example will keep things very simple. The scrolling content will simply consist of a `NestedScrollView` containing a `TextView` displaying a very long string. Notice the use of NestedScrollView rather than ScrollView. `CoordinatorLayout` knows how to interact with `NestedScrollView`, so If you want coordinated scrolling behaviors, you must use it over `ScrollView`.

The scrolling view must be a direct child of the `CoordinatorLayout` as it will later interact with its sibling view (the `AppBarLayout`).

 <!-- Scrolling Content -->  
 <android.support.v4.widget.NestedScrollView  
 android:layout_width="match_parent"  
 android:layout_height="match_parent"  
 app:layout_behavior="@string/appbar_scrolling_view_behavior"  
 android:padding="@dimen/activity_horizontal_margin"  
 android:clipToPadding="false"  
   >  
 <TextView  
   android:layout_width="match_parent"  
   android:layout_height="wrap_content"  
   style="@style/TextAppearance.AppCompat.Large"  
   android:text="@string/lorem_ipsum"  
   />  
 </android.support.v4.widget.NestedScrollView>  

Notice the `app:layout_behavior` attribute on the `NestedScrollView`. That attribute informs the `CoordinatorLayout` that the view scrolls and will allow other content to react to those scrolling events accordingly.

Time to add the AppBar

To add a `Toolbar` that can be expanded and collapsed three support library widgets can be used:

1. AppBarLayout
2. CollapsingToolbarLayout
3. Toolbar

These views will be nested in the order in which they were included above. They should be placed within the root layout as a direct child of the `CoordinatorLayout` and as a sibling of the scrolling content.

 <!-- AppBar content -->  
 <android.support.design.widget.AppBarLayout  
 android:layout_width="match_parent"  
 android:layout_height="192dp"  
 >  
 <android.support.design.widget.CollapsingToolbarLayout  
 android:layout_width="match_parent"  
 android:layout_height="match_parent"  
 app:layout_scrollFlags="scroll|exitUntilCollapsed"  
 >  
 <android.support.v7.widget.Toolbar  
   android:id="@+id/toolbar"  
   android:layout_width="match_parent"  
   android:layout_height="?attr/actionBarSize"  
   android:background="?attr/colorPrimary"  
   />  
 </android.support.design.widget.CollapsingToolbarLayout>  

There are a few interesting things in this layout to point out:

1. The expanded size of the AppBar is controlled by the height attribute of the `AppBarLayout`.

2. The collapsing behavior of the AppBar is controlled by the `app:layout_scrollFlags` attribute.  In the example above the `scroll` value specifies that the `CollapsingToolbarLayout` should respond to scroll events, and the `exitUntilCollapsed` value specifies that the AppBar should shrink in size until it reaches it's collapsed (min) height.
3. The min height is controlled by the height of the `Toolbar` within the `CollapsingToolbarLayout`

One of the great things about `CoordinatorLayout` and some of its supporting cast members is that the behaviors of different views can be easily customized through xml without ever touching your code.  This makes it very easy for a developer or designer to quickly try different behaviors withing having to modify any Java code!!!

And there you have it.  A simple implementation of a collapsing, extended height AppBar.  For a information you can follow the video link below, or you can check out the sample code on GitHub.

Video Tutorial
Sample Code

I love to meet/talk/discuss and help where I can. If you want to chat or ask a question you can follow me on Twitter, YouTube, Instagram and Facebook.

Check Out My YouTube Channel

MarvelAndroid

I’m happy to say that Beta 1 of MarvelAndroid is available!

What is it for?

This library is aimed at making it easier for developers to make awesome comic book apps with the Marvel Comics Api. There is a wealth of awesome Marvel content available through the api, and with MarvelAndroid quickly accessing that content is now easier than ever.

What can it do?

MarvelAndroid supports retrieving content for each of the 6 core entity types the API makes available:

– Characters
– Comics
– Events
– Series
– Stories
– Creators

This content can be queried in a number of ways. You can perform a general search to return all comics, all series, etc. Or, you could search for all comics associated with a specific event or maybe search for all characters whose name starts with “spider”.

See the Interactive Documentation for a full list of ways in which content can be queried.

Initialization

To use this library, you must first initialize it within your code using your own public and private keys acquired from the [Marvel Developer Portal](http://developer.marvel.com/).

 MarvelAndroid.initialize(context, "your private key", "your public key", cacheSize);  

Searching

Lets take a look at an example of searching for a content. In this case we want to retrieve all characters whose name starts with “spider”.

First, create a `CharacterQueryParams` object to define the characters query.

 CharacterQueryParams queryParams = new CharacterQueryParams();  
 queryParams.setNameStartsWith("spider");  

Next, get an instance of `CharacterEndpoint`.

 MarvelAndroid marvelAndroid = MarvelAndroid.getInstance();  
 CharacterEndpoint characterEndpoint = marvelAndroid.getCharacterEndpoint();  

Through the endpoint, characters can be return through a number of methods such as `getCharacter()` and `getCharactersForComicId()`. Each method has two forms as well. One that takes a callback, and another that returns an RxJava Observable.

 characterEndpoint.getCharacters(queryParams, new Callback<RequestResponse<Character>>() {  
   @Override  
   public void success(RequestResponse<Character> characterRequestResponse, Response response) {  
   }  
   @Override  
   public void failure(RetrofitError error) {  
   }  
 });  
 Observable<RequestResponse<Character>> characters = characterEndpoint.getCharacters(queryParams);  

Handling results

With the returned response, a list of characters matching the specified query can be accessed. The results are returned in pages, with a default page size of 20. The page size and current page offset can be set through the `CharacterQueryParams`.

 characterEndpoint.getCharacters(queryParams, new Callback<RequestResponse<Character>>() {  
   @Override  
   public void success(RequestResponse<Character> characterRequestResponse, Response response) {  
     List<Character> characters = characterRequestResponse.data.results;  
     for (Character character : characters) {  
       print("Name: " + character.name + " Id: " + character.id + " Description: " + character.description);  
     }  
   }  
   @Override  
   public void failure(RetrofitError error) {  
   }  
 });  

Lets add another endpoint

In the previous example, we retrieved a list of characters. Now, lets look at how you could retrieve a list of comics for a returned character.

 ComicQueryParams queryParams = new ComicQueryParams();  
 queryParams.setOrderBy(ComicQueryParams.OrderBy.Title);  
 for (Character character : characters) {  
  marvelAndroid.getComicEndpoint().getComicsForCharacterId(character.id, queryParams, new Callback<RequestResponse<Comic>>() {  
    @Override  
    public void success(RequestResponse<Comic> requestResponse, Response response) {  
     List<Comic> comics = requestResponse.data.results;  
     for (Comic comic : comics) {  
       print("Title: " + comic.title + " Description: " + comic.description);  
     }  
    }  
    @Override  
    public void failure(RetrofitError error) {  
    }  
  });  
 }  

Images

One of the best parts about comics, and Marvel’s API is all the incredible artwork that is available. For any entity, you can retrieve a partial url path that can be used to build a full url to an image representation of the entity. Each image can be accessed as a variety of variants which are documented here.

 comic.thumbnail.path + "/" + "image variant name" + "." + comic.thumbnail.extension  

http://i.annihil.us/u/prod/marvel/i/mg/2/e0/55d225446d1c0/landscape_medium.jpg

http://i.annihil.us/u/prod/marvel/i/mg/2/e0/55d225446d1c0/portrait_incredible.jpg

Use and Contribute

You can view/download the code at GitHub.

Please give feedback, log any issues you find, or create enhancement requests.


I love to meet/talk/discuss and help where I can. If you want to chat or ask a question you can follow me on Twitter, YouTube, Instagram and Facebook.

Check Out My YouTube Channel