25 January 2016

Using a mock RESTful API with Android OkHttp and getSandbox

I recently stumbled across a really cool service called getSandbox.com. This is a API mocking service which can mimic RESTful or SOAP webservices. This is incredibly useful for knocking up quick testing tools or as an endpoint for unit tests.


This has huge advantages as it allows you to protect your server from unit test bombarding, however I'm more interested in just being able to use it just to quickly setup a few examples for prototyping. You can deploy it on your server or using their cloud, but they offer a free tier just for a low number of requests.


So I decided to setup a getsandbox account and use it with okHttp on Android to see if I can do some simple REST get and post requests.




First I created a new sandbox, I didn't have an Apiary account and this is a test API so I've no WSDL nor a RAML and I don’t know what Swagger is. So I picked blank. This is great, it gives you a temporary one hour sandbox with a few simple get and post methods.


  • GET/hello - Respond hello world
  • GET/users - Show all users
  • POST/users - Add new user


Sandbox even gives you some form of storage, so anything you add is persistent.


With my new endpoints I created a form (see below) to test the POST and in a browser hit the main url to get all users. Magic, everything is responding wonderfully. Sandbox is really that simple and easy to use! I'm super impressed.


Next we’re over to Android and I wanted to use OkHttp for this one. OkHttp is a neat little library that handles http requests for you and easily deals with any problems. Plus it can make synchronous and asynchronous calls with ease.

I created a new Android Studio project and added in the okhttp gradle compile:

compile 'com.squareup.okhttp3:okhttp:3.0.1'

Then I put INTERNET permissions in the manifest, a ListView in my activity view and started the java code. First I made my activity implement okhttp3.Callback, most tutorials will tell you to put the callback inside the method call, but personal preference, I like implements.
Here’s the simple OkHttp code:

OkHttpClient client = new OkHttpClient();
//Create a simple get request
Request request = new Request.Builder().url(sUrl).build();
//Execute with call back
client.newCall(request).enqueue(this);

You don’t get much simpler than that. The request is a fairly self evident GET request, nothing in the body and nothing fancy.
Next you have a choice,


client.newCall(...).execute or .enqueue.


Execute is a blocking synchronous call whilst enqueue is an asynchronous call. We’ll use enqueue as we can’t do a blocking call on the UI thread anyway.

So my Activity now overrides onFailure onResponse

@Override
public void onResponse(Call call, Response response) throws IOException {
  Log.i("http", "onResponse");

  int j = 0;
  String[] users = null;

  try {
     //Read string in as json array
     JSONArray jsonArray = new JSONArray(response.body().string());

     users = new String[jsonArray.length()];
     //add each element in array to string array
     for (int i = 0; i < jsonArray.length(); i++) {
        if(jsonArray.get(i) != null) {
           users[j] = jsonArray.get(i).toString();
           j++;
        }
     }
  } catch (JSONException e) {
     e.printStackTrace();
  }

  if (users != null){
     //Create adapter of users
     mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, users);

     //listview needs to be updated on ui thread.
     runOnUiThread(new Runnable() {
        @Override
        public void run() {
           mListView.setAdapter(mAdapter);
        }
     });
  }
}


That's pretty much it. The code in onResponse isn't rocket science. We take the response from OkHttp and parse it as a json array. We can now loop through it and create a normal String array. We could do a bit more error checking here and clean some dodgy input, but for sake of speed that's your lot. The only slight oddity is having to set the listview using runOnUi because we can't change the UI elements outside of the UI thread. The again....now I think, I didn't really need to set that after the data did I? I could have done that in the Acivity onCreate....oh well, next time!

So look what we've done in just a few lines of code and a few clicks. We've done some web interaction without any need for asyncs or checking if we have a connection. Plus we've got a fantastic test API which responds quickly, updates instantly and is super easy to use.


Just in case you need to submit to a POST, here's my mega javascript form:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                $('#submit').click(function(){
                
                    console.log('hiii');

                    $.ajax({
                        url: "http://**myid**.getsandbox.com/users",
                        type:'POST',
                        data:
                        {
                            username: $('#username').val()
                        },
                        success: function(msg){
                            $('#username').val("");
                        }               
                    });

                    return false;
                });
            });
        </script>
    </head>

    <body>
        <form>
            <input type="text" name="username" id="username" value="" />
            <button name="go" id="submit">Submit</button>
        </form>
    </body>
</html>


11 November 2015

Android layout with view fixed to bottom


I recently submitted a stack overflow question about a problem I was having. I didn't get the answer I was looking for so eventually I answered it myself.

The concept I wanted to achieve was to have a view stick to the bottom of the screen. Pretty easy in a relative layout with alignParentBottom="true". However the screen was a registration screen, so it had edit text boxes. When you click on an edit text box, the soft keyboard appears. The problem I then had of course was that my bottom view then popped up to the top of the keyboard and obscured most of the screen.



The above diagram goes a little way to representing what I was seeing, with three being the keyboard and two being the view I wanted stuck to the bottom. The overall container being a RelativeLayout with the blue being a ScrollView and the red alignParentBottom="true".

After much head scratching I finally stumbled across a solution, although it was a bit different to what I was expecting.

First I moved the red bottom view into the scrollview and added a stretcher view with a height of zero.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:isScrollContainer="false">

        <LinearLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <EditText />
            <EditText />

            <View
                android:id="@+id/stretcher"
                android:layout_width="match_parent"
                android:layout_height="0dp" />

            <TextView
                android:id="@+id/2"
                android:layout_gravity="bottom"
                text="2" />
        </LinearLayout>
    </ScrollView>
</RelativeLayout>


The next step was to add a view tree observer.

    final View mainLayout = getView();
    final View mainContent = getView().findViewById(R.id.content);
    final View stretcherView = getView().findViewById(R.id.stretcher);

    //Main layout uses weight some, so we can't hard code the size of the circles.
    //We must dynamically re-size
    mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (android.os.Build.VERSION.SDK_INT >= 16) {
                mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            //Calculate the desired height of the stretcher view to be the remainder between full screen and content.
            int stretchHeight = mainLayout.getHeight() - mainContent.getHeight();

            //Apply calculated height remainder to stretched view.
            //This enables our bottom box to be pushed to the bottom without obstructing the content when the keyboard appears.
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) stretcherView.getLayoutParams();
            params.height = stretchHeight;
            stretcherView.setLayoutParams(params);
        }
    });


This listener watches the entire screen and then measures the difference between the full screen and the scrollview. It then inflates the stretcher view by this difference. What we're effectively doing is nudging the bottom view to the bottom of the screen. Now when we load the page the bottom view sits nicely on the bottom of the screen, but when the keyboard moves the bottom view stays underneath and appears in the scroll.

Hope this helps somebody else!

27 October 2015

Android custom view, interesting lessons


So here's an interesting one, I recently created a custom view in Android. Basically a specific shape that a client wanted to frame some text. To begin with the custom view was very simple and I used a relative layout to hold the view in place and the centred brand name inside.


The java comprised of a Paint with a fill in the view initializer and in the onDraw method a Path drawn on the canvas with drawPath().

Unfortunately vertical centre was of the whole view, I needed it to be centred by the left side (a). Remember the view is more than what you can see and in this case it includes the invisible part of the rectangle above the slope. My first impulse was to push it down with some marginTop, but this would of course not work consistently on smaller devices.
So what I needed to do was measure a and centre the text accordingly. I grabbed height and width in onMeasure using MeasureSpec.getSize. Then used the following code to I found on stack overflow:

int yPos = (int) ((mHeight / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2));
canvas.drawText("", 20, yPos, mTextPaint);

This allowed me to centre the text as required. I added a paint object with some formatting:

        //Text font
        mTextToShow = getContext().getResources().getString(R.string.some_text);
        Typeface ty = Typeface.createFromAsset(getContext().getAssets(), "fonts/some_font.otf");

        //Text size
        Resources resources = getContext().getResources();
        float scale = resources.getDisplayMetrics().density;

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize((int) (20 * scale));
        mTextPaint.setTypeface(ty);
        mTextPaint.setColor(getResources().getColor(R.color.primary_white));


I now needed to do one more thing, the view was to be a link. I'm a huge fan of using Android's state to change text colour when its clickable. This helps the user know they've clicked something and it looks good too. However I had no idea how to do this, if I'd made an xml layout for this view I could do it, but using drawText meant I had no xml. Hmmm.

A few Google searches and even the mighty stack overflow didn't get me very far. Then I started to think, don't all view's have a onPressed or an onStateChanged method? I hit Ctrl Space and scanned through my options. OnPressed was there but I needed more... drawableStateChanged. Sounds promising. A few minutes later I had a working guess and it was building. Hey preseto! It worked, check this out:
    @Override
    protected void drawableStateChanged() {
        if(isPressed()){
            mTextPaint.setColor(getResources().getColor(R.color.primary));
        }else{
            mTextPaint.setColor(getResources().getColor(R.color.primary_white));
        }
        invalidate();

        super.drawableStateChanged();
    }

Hope this helps, happy coding


28 July 2015

Top Ten Free Android Wear Watch Faces

I've recently got myself an Android Wear Watch. It’s actually an Asus ZenWatch and thus far I’ve really enjoyed it. In using it I'm constantly on the lookout for new and attractive watch faces. There are hundreds of different watch faces out there and developers build more every day. I myself have created a few watch faces and am looking forward to launching a new digital watch face soon. I thought I’d do a list of my favourite free watch faces.

I’ll specify that the following list of free watch faces are almost all digital. Yes I’m one of those people who own a digital watch. I dislike analogue watches and always will.

Orbiting this at a distance of roughly ninety-eight million miles is an utterly insignificant little blue-green planet whose ape-descended life forms are so amazingly primitive that they still think digital watches are a pretty neat idea.
- Douglas Adams (Hitchhiker's Guide To The Galaxy)

Here is a list of the top ten free watch faces I’ve found so far:

  1. Weather Watch face
    https://play.google.com/store/apps/details?id=com.pizzaentertainment.weatherwatchface&hl=en
    This is a really beautiful watch face. Granted it’s “fremium”, you can install it for free and then pay for more features, but the basic model is really great.
  2. LED Clock
    https://play.google.com/store/apps/details?id=com.seenapps.ledclock_face&hl=en
    Very simple, very elegant, I really like this watch face. Just LED numbers, nothing else.
  3. Word Clock
    https://play.google.com/store/apps/details?id=de.amnoid.thakis.wordclock&hl=en
    I love this watch face, whoever thought of this is a genious. I wish I’d come up with the idea. It shows the time as words, which is really fun. No date and no battery info.
  4. Binary
    https://play.google.com/store/apps/details?id=com.halachev.martin.android.wearable.binarywatchface&hl=en
    The ultimate geek watch face. Time displayed in highlighted circles representing 8,4,2,1 for the hour and so on. Really clever. Date in the background can be a bit hard to decipher and day of the week is missing.
  5. Matrix
    https://play.google.com/store/apps/details?id=net.dheera.wearfacematrix&hl=en Probably not great for battery and becomes a little annoying. Still a really fun idea. Doesn’t display any date or battery levels.
  6. Space and Time
    https://play.google.com/store/apps/details?id=net.genggao.spaceandtime&hl=en
    Colourful and fun, these things please me.
  7. Vigor Watch Face
    Comes free with either Google Wear or Asus, either way it’s a lovely little watch face. Ties nicely into the numbers of steps you’ve done in a day.Lacks the month and year, but I should really know that shouldn’t I?
  8. QWF
    https://play.google.com/store/apps/details?id=qwf.ammarptn.com.qwf&hl=en
    This is a really lovely little watch face. Super simple, super pretty. It lacks a day of the week and some of the information the others have, but that’s excusable.
  9. Un Petit Monde
    https://play.google.com/store/apps/details?id=net.unpetitmonde.miniadventure.watchface
    No options, battery and limited date display, but a fun design with a relaxing background effect.
  10. Simple Watch Face
    https://play.google.com/store/apps/details?id=com.koherent.simplisticwatchface&hl=en
    Does exactly what it says on the tin. A nice simple watch face with good colours and a good idea for a theme. No 24 hour, no date, no battery.




09 July 2015

Android Wear - A week with a smartwatch

Thus far, I've not been impressed with smartwatches, I like new toys but even Android Wear has yet to impress me. The watches are just too big, I don’t buy into the charging every day thing and frankly I'm just not excited about the benefits. I've had a Casio watch which I've worn every day for about fifteen years and I've never charged it. Not once!

Roughly a week ago my work bought an Asus Zenwatch running Android Wear for testing and developing on. Not one to look a gift horse in the mouth and always up for some new programming and tinkering I was quite looking forward to having a play. I've previously written a test app but I used an emulator for this: http://webdeveloperpadawan.blogspot.co.uk/2014/07/android-wearables-first-go.html

My first impression of the Zen Watch was actually very good. It’s not nearly as fat as the LG Moto 360 which a few of my colleagues have and both the leather strap and the face have a nice look and feel. It is square but I can’t imagine that would bear any consequence to anyone.

It is too big, my tiny girl wrists are very twig like and the watch doesn't fit well and looks huge. There are huge gaps in the corners where the watch overlaps the flat bit of my wrist. That said it is comfortable and easy to get used to.

Turn on and set-up are a breeze and you can play with the watch faces on the play store which is fun for a few minutes.

Then it hits you….what now? You can’t really do anything with it! This is what is quite funny, people spot it on your wrist quite quickly and you honestly can’t show them much. It’s a passive device, you can’t play games on it, you can’t type on it, it just responds.

Sure you can use OK Google which is impressive, but I don’t talk to my phone and I’m unlikely to talk to this. It does work well and you can send messages and such by talking. Word to the wise, don’t try this after half a bottle of wine as I ended up sending all sorts of random messages to various people.

The beauty of the watch, and where I'm finally coming to actually really like it, is when you need to react to something. For example when one of the millions of spam messages comes to my phone, I don’t actually need to get my phone out to check it. I can immediately check and prioritise what’s important. The other thing that really stands out is the vibrate on your wrist, this is great as I often miss a call or message on my phone. The wrist vibrate is subtle but also unmissable. The ability to not get your phone out of your pocket sounds unbelievably lazy, but the watch works. For example in meetings or when you’re busy doing something, you can prioritise at a glance. Is this just another meaningless message from some inane whatsapp group or is it a message from Nest saying my house is on fire?

The battery is much less of a big deal than I thought, I'm getting two or three days of use out of it (I turn it off at night) and can just chuck it on its gradle for a bit while I'm working on it. Will it get tired….possibly, but so far its really not bothered me.

The Oatmeal have a fantastic post about the watch, all be it the apple one…. and it’s got funnier pictures than I do:

So to summarize, I'm impressed, very impressed. It can be surprisingly useful and does make life much easier. Million dollar question, would I buy one? No. They’re too big, when technology advances and the size comes way down, yes I will.

16 June 2015

Android integration with Chrome Custom Tabs


Announced at Google IO 2015 was the ability to integrate custom tabs in Android. Much like Facebook has been using it’s own browser like tab to open links, this ability is now available in Android with Chrome. This is great news as it allows developers to integrate a web link and maintain some of the look and feel of their app. You can add toolbar colors, animations and even a button.


Before going any further as of June 2015 you need to install Chrome from the dev channel:
Version 45 has this feature, they say it’ll take about twelve weeks to roll through to release.

This works in any version of Android, so don’t worry about M or any of that. It degrades really nicely, so if your client has the feature in Chrome, it’ll slide in and out beautifully. If not, then it’ll open like a regular intent. Although your custom in animation will probably show.

First you need to create four standard in and out animations, left in, left out, right in, right out.
Then you need to define some final constants which will be used in the intent extras:
private static final String EXTRA_CUSTOM_TABS_SESSION_ID = "android.support.CUSTOM_TABS:session_id";
public static final String EXTRA_CUSTOM_TABS_EXIT_ANIMATION_BUNDLE = "android.support.CUSTOM_TABS:exit_animation_bundle";
private static final String EXTRA_CUSTOM_TABS_TOOLBAR_COLOR = "android.support.CUSTOM_TABS:toolbar_color";

Then you can launch like this from your activity:

String url = "http://www.google.com/";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.putExtra(EXTRA_CUSTOM_TABS_SESSION_ID, -1);
intent.putExtra(EXTRA_CUSTOM_TABS_TOOLBAR_COLOR, getResources().getColor(R.color.colorPrimary));

if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    Bundle finishBundle = ActivityOptions.makeCustomAnimation(MainActivity.this, R.anim.slide_in_left, R.anim.slide_out_right).toBundle();
    intent.putExtra(EXTRA_CUSTOM_TABS_EXIT_ANIMATION_BUNDLE, finishBundle);
    Bundle startBundle = ActivityOptions.makeCustomAnimation(MainActivity.this, R.anim.slide_in_right, R.anim.slide_out_left).toBundle();
    startActivity(intent, startBundle);
}else{
    startActivity(intent);
}


Note that basically all we are doing is launch an intent.ACTION_VIEW but we’re tweaking it with extras so Chrome can interpret this request, slightly differently.
That’s it!

31 May 2015

Android Design Support Library Collapsing Toolbar


Following Google IO I'm always that much more inspired to try a few new things with Android.
Shortly after IO I noticed this new post on the devlopers blog:
http://android-developers.blogspot.co.uk/2015/05/android-design-support-library.html

I immediately loved the CollapsingToolbarLayout as I've had to make something similar myself and never quite got it perfect. The fact that Google are releasing quick and easy ways to implement these design elements is absolutely fantastic. Long may it continue!

When I saw Ian Lake's post on this collapsing toolbar I was super keen to give them a go:
https://plus.google.com/+IanLake/posts/QGR5XNcPPeG

I didn't get especially far until this example from Chris Banes:
https://github.com/chrisbanes/cheesesquare

I decided (as usual) to make mine as simple as possible, stripping out as much of the superfluous stuff as I could.

First we need the support and design libraries:
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.0'

First thing we'll do is the xml for our main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <TextView
            android:text="@string/hello_world"
            android:padding="20dp"
            android:layout_width="match_parent"
            android:textColor="#00FF00"
            android:layout_height="wrap_content"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/activity_main_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

The important bit here is the AppBarLayout which contains the Toolbar and a TextView which I want to hover over the top of the listview.

Second you'll notice we're using a RecyclerView which is new to me but looks to be more powerful than Listview.

Our ActivityMain just passes an ArrayList of Strings too the Recycler View
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.activity_main_listview);
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new MyRecyclerView(this, players));

Oh and of course don't forget to make sure your Activity uses AppCompatActivity and your manifest has a theme which overrides or implements Theme.AppCompat.Light.NoActionBar
You'll need the MyRecylcerView class but that's fairly boring and I borrowed most of it from Chris Banes, so I'll let you look at that in the git repo (bottom).

Now we need to look at the detail page where we use CollapsingToolbarLayout. First the xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:theme="@style/ActionBarPopupThemeOverlay"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:theme="@style/ActionBarPopupThemeOverlay"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:textColor="@color/colorAccent"
                android:text="All your base are belong to me." />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Here we use a NestedScrollView instead of a RecyclerView, hence the big list of TextViews

The Activity is even simpler here, we read in the extra and setup the toolbar title and background image, then setup the action bar so it's an up navaigation and set the title:
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(muppetName);

That's basically it, a few new concepts and tools here but its super easy.

Here's the GitHub repo of all of this:
https://github.com/jimbo1299/androiddesigntest