HACKMIT 2019 This Weekend!

HackMIT is this weekend, September 14-15th.

I’m happy to announce that I’ll be mentoring as one of the local Microsoft MVPs that were invited to help as part of the Microsoft sponsorship of the event. I look forward to building some incredible applications with some of the brightest students coming to Cambridge! Hack for a reason 🙂

Check out some of the awesome tracks:

hackmit_tracks

 

If you’re hacking this weekend, come find me for help with:

  • Conversational AI
  • Voice First Development
  • Azure
  • AWS
  • Machine Learning
  • Unity
  • C#
  • JavaScript/TypeScript
  • Kotlin
  • React
  • Video Editing
  • and RTC

See ya’ll there!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Advertisements

Video – Kotlin for C# Developers at NDC Oslo

In June, I had the amazing privilege of giving a talk at NDC Oslo called “Kotlin for C# Developers”! Lucky for you, NDC records all of their sessions, so you can check out the recording from YouTube right here 🙂

Dive into the latest craze in languages and platforms – Kotlin. This time we will be looking at it from the perspective of a .NET C# developer, draw comparisons between the languages, and bridge the gap between these 2 amazing languages.

We’ll look at:
– Kotlin as a language
– Platforms Kotlin is great for
– Object Oriented Implementations in Kotlin
– Extended Features
– Features Kotlin has that C# doesn’t
– A demo Android application in Kotlin vs a Xamarin.Android app in C#

In the end you will leave with a foundational knowledge of Kotlin and its capabilities to build awesome apps with less code. You should feel comfortable comparing C# applications to Kotlin applications and know where to find resources to learn even more!

Let me know your thoughts in the comments or on Twitter, and check out my other content on Kotlin here: https://alexdunn.org/tag/kotlin/

Want to see this live? I’ll be giving an updated version of this talk at Techorama Netherlands in September/October along with an introduction to the Flux design pattern in C#.

Check those out here:

If you prefer to just jump right into a language / platform – I would happily suggest my Pluralsight course – Building Android Apps with Kotlin: Getting Started. Take a look here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/

 

 


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Conversation Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


New Pluralsight Android Skill IQ Tests

I recently worked with Pluralsight (pluralsight.com) to help produce 2 brand spankin’ new Skill IQ Tests! Test your skills and knowledge of Android development, Android Studio, Kotlin and more!

Android Tooling Skill Assessment

The first is Android Tooling! You can test your knowledge of:

  • Android Studio – Analyze
  • Android Studio – Basics
  • Android Studio – Build
  • Android Studio – Code Manipulation
  • Android Studio – File Structure
  • Android Studio – Run
  • Android Studio – Settings
  • Android Studio – Tools
  • Android Studio – Version Control
  • Gradle

Although this exam is still in Beta (as of writing this post), you can still take the exam and I encourage you to as well! Pluralsight does some really cool work to calibrate the curve of the skill assessment so give it a go and let me know how you do 🙂

Take it here: https://app.pluralsight.com/score/skill-assessment/android-tooling/intro#/v2/landing 


Kotlin: Enhancing App Experience

The second skill assessment is for you Kotlin lovers like me and dives into some deeper knowledge of building better Android apps with Kotlin!

Kotlin is an open-source JVM language created by JetBrains. It is one of the most popular languages used in Android development.

The assessment may cover:

  • Activities
  • Enhanced System Integration
  • Threading and Background Work
  • User Interface and Experience

This assessment is also still in Beta, but be sure to try this one out and see if your Kotlin skills are up to snuff.

Check Out My Course!

Oh wow how topical and convenient! Be sure to check out my course on Building Android Apps with Kotlin: Getting Started to learn a lot about the fundamentals of both the Kotlin language and Android development as a whole! I assure it will help drive that Skill IQ Up for both of these assessments 🙂 

https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started 

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Android Kotlin Basics – Lazy Loading Images with Picasso

About This Series

This “Android Kotlin Basics” blog series is all about fundamentals. We’ll take a look at the basics of building Android apps with Kotlin from the SUPER basics, to the standard basics, to the not-so-basics. We’ll also be drawing comparisons to how things are done in Kotlin vs. Java and some other programming languages to build Android apps (like C# and Xamarin or JavaScript/TypeScript for Hybrid implementations).

Find other posts in this series: Android Kotlin Basics

Check Out the Pluralsight Course!

If you like this series, be sure to check out my course on Pluralsight – Building Android Apps with Kotlin: Getting Started where you can learn more while building your own real-world application in Kotlin along the way. You can also join the conversation and test your knowledge throughout the course with learning checks through each module!

Watch it here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/table-of-contents

Lazy Loading Images with Picasso

Loading images from remote sources without help can be a pain in Android development. You need to make the http request against the url, download the bytes of the image, create a Bitmap from those bytes, then render that BitMap in an ImageView. Not only is that tedious, but it also leaves room for tons of errors and especially the dreaded OutOfMemoryException that happens oh so often when trying to render large images in Android.

There are some really great libraries out there for helping face this issue that can also provide some other useful tools such as filtering, extensions, customizing, and more.

In the course we use Picasso which is a library by Square to help lazy load images. Find it here: http://square.github.io/picasso/

Picasso does a great job loading images asynchronously and handles rendering them with proper scale. It does a great job handling this performance in ListViews and RecyclerViews as well. This is exactly how we use it in our real-world app that we build in the course!

Picasso also has some great features with creating custom transformations or extending the functionality. In this post we will stick to the basics though. If you want to get into details check out the Java documentation at their website. Copy and pasting that into a Kotlin file in Android studio will also automatically translate it for you!

Installing

Picasso can be installed 3 ways:
– Gradle (what we use in the course)
– Maven
– Manual

To install with gradle, add:

implementation 'com.squareup.picasso:picasso:2.71828'

to your build.gradle config.

For maven use:

<dependency>
  <groupId>com.squareup.picasso</groupId>
  <artifactId>picasso</artifactId>
  <version>2.71828</version>
</dependency>

And if you want to do it manually, download the jar from http://square.github.io/picasso/ and reference it in your project.

Basic Image Loading

Now that you have Picasso in your project, lets look at how we can do simple image loading.

Let’s start with a simple layout:

activity_main.xml

<RelativeLayout 
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <ImageView android:id="@+id/myImageView"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />
</RelativeLayout>

Now in our Activity code, we can load the image from the url in the onCreate override.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // load the image with Picasso
        Picasso
            .with(this) // give it the context
            .load("https://i.imgur.com/H981AN7.jpg") // load the image
            .into(myImageView) // select the ImageView to load it into
    }
}

If you’re unsure of why we didn’t need to call

val myImageView = findViewByid<ImageView>(R.id.myImageView)

Check out my post on how Kotlin automatically maps views to properties by id: Android Kotlin Basics – Auto-mapping Views

And that’s it! Now you have automatically handled all performance concerns, caching needs, sizing and downloading, and so much more!

Using in a RecyclerView

So loading a single image into a single ImageView isn’t so bad on its own, but when you have to load high-res images into large lists that can change all the time, there are a lot of places this can go wrong doing it yourself. Developers often run into:
– Lag on new items appearing
– Mismatched images
– No images loading
– Images loading incorrectly
– Dreaded Out of Memory Exceptions

Because Picasso runs the image loading asynchronously and only touches the UI thread when it needs to render the image itself, it avoid the issues of locking the UI up when loading. Because it also caches the images locally, when the image needs to be loaded again (such as scrolling back up), it does so quickly and can void mismatching renderings. Also, because it renders the image in chunks before showing it, they avoid the easy to find Out of Memory Exception that we have all come to hate when trying to render a large image into an ImageView. Normally to avoid this, you have to manually load a scaled down image into memory and handle how you scale it per image. Picasso does all this for us too.

On top of all that, Picasso ships with some of the nice-to-haves such as:
– Transitions when images load or change
– Placeholder images to show while loading from a url
– Transformations on images once loaded
– Debugging indicators to show where the image loaded from

All these great features even scale to these large lists and RecyclerViews.

Before showing how to use it in your RecyclerView, be sure to check out the other post in this series: Android Kotlin Basics – RecyclerView and Adapters unless you’re already familiar with how RecyclerViews and Adapters work 🙂

We can create a layout for our item in our list:

image_item.xml

<ImageView android:id="@+id/myImageView"
    android:layout_height="match_parent"
    android:layout_width="match_parent" />

Then a ViewHolder for this image:

ImageHolder.kt

class ImageHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val myImageView: ImageView = itemView.findViewById<ImageView>(R.id.myImageView)

    fun updateWithUrl(url: String) {
        Picasso.with(itemView.context).load(url).into(myImageView)
    }
}

Now let’s create our Adapter with our datasource:

ImagesAdapter.kt

class ImageAdapter() : RecyclerView.Adapter<ImageHolder>() {
    val imageUrls: Array<string>

    init {
        imageUrls = arrayOf("https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg", "https://i.imgur.com/kUCMPWX.jpg")
    }

    override fun getItemCount(): Int {
        return imageUrls.size;
    }

    override fun onBindViewHolder(holder: ImageHolder?, position: Int) {
        var imageUrl = imageUrls[position]
        holder?.updateWithUrl(imageUrl)
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ImageHolder {
        var imageItem = LayoutInflater.from(parent?.context).inflate(R.layout.image_item, parent, false)
        return ImageHolder(imageItem)
    }
}

Last we just need to create our Activity and wireup the Adapter!

activity_main.xml

<RelativeLayout 
    android:layout_height="match_parent"
    android:layout_width="match_parent">    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/imageRecycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        imageRecycler.layoutManager = LinearLayoutManager(this)
        imageRecycler.adapter = ImageAdapter()
    }
}

Now we can quickly scroll through our list and see the images loaded quickly and properly into our view!

dogs


Also, let me know what else you’d like to learn about with Android and Kotlin! Either drop a comment here or tweet at me @Suave_Pirate!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Android Kotlin Basics – Passing Data Between Activities

About This Series

This “Android Kotlin Basics” blog series is all about fundamentals. We’ll take a look at the basics of building Android apps with Kotlin from the SUPER basics, to the standard basics, to the not-so-basics. We’ll also be drawing comparisons to how things are done in Kotlin vs. Java and some other programming languages to build Android apps (like C# and Xamarin or JavaScript/TypeScript for Hybrid implementations).

Check Out the Pluralsight Course!

If you like this series, be sure to check out my course on Pluralsight – Building Android Apps with Kotlin: Getting Started where you can learn more while building your own real-world application in Kotlin along the way. You can also join the conversation and test your knowledge throughout the course with learning checks through each module!

Watch it here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/table-of-contents

Passing Data Between Activities

This topic is covered in depth in the course above, but in this post, we’ll quickly go over this basic, but very important concept when developing your Android mobile apps.

Let’s break it down first –

I Have No Idea What an “Activity” Is

Not to worry! Here’s the basic idea – it’s a construct (and a class in your code) that represents an entry point for your app and can be called into by your other Activities. You can think of an Activity as a contextual “page”, and thus your app will likely have multiple Activities.

Activities can do a lot, but for simplicity sake, we’ll only talk about the most common implementation which is this idea of a drawing a window of your application.

Starting an Activity

When you create your application, you’ll have to register your Activities to your Android manifest. Doing this tells the operating system which Activities you have in your app, where to find them, what they can do, and some other information we won’t get into in this topic.

That looks something like this:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.alexdunn.wikipedia">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:name=".WikiApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme.NoActionBar">
        <activity
            android:name=".activities.MainActivity"
            android:label="@string/title_activity_main">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activities.ArticleDetailActivity"></activity>
        <activity android:name=".activities.SearchActivity"></activity>
    </application>

</manifest>

This is a manifest with 3 Activities, MainActivity, SearchActivity, and ArticleDetailActivity.

Once all Activities are registered in the Manifest, we can start any of them from any other.

Let’s look at a quick example where we are in the MainActivity and want to start the SearchActivity on a button click:

MainActivity.kt

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        my_button.setOnClickListener {
            // create an "Intent"
            val searchIntent = Intent(this, SearchActivity::class.java)

            // start the activity with the intent
            startActivity(searchIntent)
        }
    }
}

So what’s this Intent object?

An Intent in Android is a construct to tell the operating system that your application is trying to execute something that needs to be communicated back to the application or a different application. This is used for many things outside just starting Activities – it can be used for executing Services, Activities, and BroadcastReceivers.

Here’s a quick diagram on how this works at a basic level:
Screen Shot 2018-03-23 at 11.02.59 AM.png

Adding Data to an Intent

So now we know we use Intents to start Activities (and do other things!), but how do we use them to actually send data to another Activity?

The Intent object has a the concept of a Extras . This means we can add different primitive datatypes to the Extras, or add Serializable data.

Here’s what that looks like in Kotlin!

// 1. create an intent from another activity
val intent = Intent(context, AnotherActivity::class.java)

// 2. put key/value data
intent.putExtra("message", "Hello From MainActivity")

// 3. start the activity with the intent
context.startActivity(intent)

The putExtra has many overloads, so play around with all the types of data you can add.

You can also add Bundles of data to group the data being sent up together:

// 1. create an intent from another activity
val intent = Intent(context, AnotherActivity::class.java)

// 2. put key/value data to bundle
val extras = Bundle()
extras.putString(“message”, “Hello from MainActivity”)
intent.putExtras(extras)

// 3. start the activity with the intent
context.startActivity(intent)

Reading Data From the Intent

Now when we use an intent to start an Activity, and add Extras, we need to be able to read those extras on the new Activity.

This works by using the intent property on the Activity. This intent property is set by the Operating System when starting the Activity, and sets it to the Intent that created it.

We usually use this data in the onCreate override, but you can use it wherever you want!

DetailActivity.kt

class DetailActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // In onCreate get the value from the auto-mapped “intent”
        val message = intent.getStringExtra(“message”)

        // Or get it from the bundle and auto-mapped “extras”
        val message = intent.extras.getString(“message”)

        // now do something with the message value
    }
}

Conclusion

There’s plenty more you can do with these data structures in Android such as sending over full datatypes and reference types, receiving data back from the detail Activity, and so much more. Be sure to check out my course: Building Android Apps with Kotlin: Getting Started to learn so much more!


Also, let me know what else you’d like to learn about with Android and Kotlin! Either drop a comment here or tweet at me @Suave_Pirate!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Android Kotlin Basics – Camel Case Or Underscore Notation

About This Series

This “Android Kotlin Basics” blog series is all about fundamentals. We’ll take a look at the basics of building Android apps with Kotlin from the SUPER basics, to the standard basics, to the not-so-basics. We’ll also be drawing comparisons to how things are done in Kotlin vs. Java and some other programming languages to build Android apps (like C# and Xamarin or JavaScript/TypeScript for Hybrid implementations).

Check Out the Pluralsight Course!

If you like this series, be sure to check out my course on Pluralsight – Building Android Apps with Kotlin: Getting Started where you can learn more while building your own real-world application in Kotlin along the way. You can also join the conversation and test your knowledge throughout the course with learning checks through each module!

Watch it here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/table-of-contents

Camel Case Or Underscore Notation

I get this type of question quite often – “If the Kotlin Android extensions allow for creating Kotlin members in my Activities, should I be using underscore IDs or camel case”?

If this question doesn’t make sense, first take a look at one of my earlier posts in this series: Android Kotlin Basics – Auto-mapping Views. The short version is that Kotlin ships with Android extensions to create properties in your Activity (and more) for your Views within the layout resource applied in the setContentView call in the onCreate override function.

Here’s the predicament – traditional Android development has set a standard for using underscores for Ids and other properties within xml resources (such as the layouts we are talking about). So that looks like this:

res/layout/activity_main.xml

...

...

Doing this would create a usable EditText property in the associated MainActivity whose name is first_name:

MainActivity.kt

class MainActivity : Activity() {
    override fun onCreate(savedInstance: Bundle?) {
        super.onCreate(savedInstance)
        setContentView(R.layout.activity_main)

        first_name.text = "My First Name!"
    }
}

So the underscore seems to look a bit off in your Kotlin code since every other member and function within a class is typically came cased. So the other option is to start camel casing your xml property values:

res/layout/activity_main.xml

...

...

Doing this would create a usable EditText property in the associated MainActivity whose name is firstName:

MainActivity.kt

class MainActivity : Activity() {
    override fun onCreate(savedInstance: Bundle?) {
        super.onCreate(savedInstance)
        setContentView(R.layout.activity_main)

        firstName.text = "My First Name!"
    }
}

Of course these are just semantics, and I’ve seen projects go either way. I personally use the underscore for Android resources simply because it is still habit, but I may find myself moving more toward camel casing. The argument I hear against moving in that direction is also that the file names themselves use the underscore naming convention, and THAT convention stemmed from an actual restriction in Android development where resource files couldn’t have any uppercased letters. That is no longer really enforced, so it should be fine to name your resource files with a camel case convention as well.

My final suggestion is to simply pick one, but stick to it. Meaning, choose up front when you start your project and be consistent throughout – including your file names. If you want to camelCase, do it everywhere. If you want to underscore_case, do it everywhere. This will allow for onboarding developers easily regardless of which you pick. But who knows… maybe this will sprout another tabs vs spaces type of debate.

Let me know which one you personally prefer!


Also, let me know what else you’d like to learn about with Android and Kotlin! Either drop a comment here or tweet at me @Suave_Pirate!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Android Kotlin Basics – RecyclerView and Adapters

About This Series

This “Android Kotlin Basics” blog series is all about fundamentals. We’ll take a look at the basics of building Android apps with Kotlin from the SUPER basics, to the standard basics, to the not-so-basics. We’ll also be drawing comparisons to how things are done in Kotlin vs. Java and some other programming languages to build Android apps (like C# and Xamarin or JavaScript/TypeScript for Hybrid implementations).

Check Out the Pluralsight Course!

If you like this series, be sure to check out my course on Pluralsight – Building Android Apps with Kotlin: Getting Started where you can learn more while building your own real-world application in Kotlin along the way. You can also join the conversation and test your knowledge throughout the course with learning checks through each module!

Watch it here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/table-of-contents

RecyclerView and Adapters

RecyclerViews are the latest way to display a dynamic collection of data in Android and are what have begun to replace the ListView control. This is because of their built in pattern to “recycle” views… the name makes sense. It also allows for more flexibility in layout and display which we will also talk about here.

In order to use a RecyclerView, you need at least the 4 main parts
1. The RecyclerView itself
2. The Adapter to control what data is tied to what view in the recycler.
3. The ViewHolder to control what view is being used within the recycler
4. The LayoutManager to determine how to layout each view in the recycler.

Together, this relationship looks like this:
Screen Shot 2018-03-01 at 11.13.38 AM

Meaning the RecyclerView needs it’s two root components set – the LayoutManager and Adapter. The adapter then uses the ViewHolder and appropriate data to manipulate the RecyclerView, and the ViewHolder uses an underlying Layout Resource to inflate the view.

In the end the process looks like this:
Screen Shot 2018-03-01 at 11.03.21 AM

Where a user scrolls the list, and as items fall out the top or bottom, they are recycled, cleaned, then re-hydrated with new data from the adapter.

So let’s break down an example of building one of these in Kotlin!

Create a RecyclerView in Your Activity

Let’s first create a simple layout for our MainActivity:
res/layout/activity_main.xml

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/article_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>

Then using the Kotlin Android Extensions talked about here: Android Kotlin Basics – Auto-mapping Views we can reference our RecyclerView by its id property.

MainActivity.kt

class MainActivity : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        article_recycler_view.adapter = ??? // we need to create an adapter!
        article_recycler_view.layoutManager = LinearLayoutManager(context)
        // note that in Java we would have to call .setLayoutManager, but Kotlin auto-maps this to a property
     }
}

We’ll come back to this MainActivity once we’ve created our Adapter. But for now we can use the pre-built LinearLayoutManager which will layout the subsequent recycled views Linearly (vertically by default, but it can be set to Horizontal as well).

Create a CardView and ViewHolder

Let’s create the layout resource for our actual article card items, and the ViewHolder to represent it.

res/layout/article_card_item.xml

<?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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.v7.widget.CardView
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_margin="16dp"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:background="@android:color/white"
        app:cardElevation="4dp">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp">
            <ImageView
                android:id="@+id/article_image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_image_black_24dp"/>
            <TextView
                android:id="@+id/article_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:gravity="center"
                android:textAlignment="center"
                android:text="Hello World!"/>
        </LinearLayout>
    </android.support.v7.widget.CardView>
</RelativeLayout>

This is a simple card with an image and title in it that looks something like this:
Screen Shot 2018-03-01 at 2.40.41 PM

And with our view, we will need to create a ViewHolder that our Adapter will use to stick data in it:

CardHolder.kt

class CardHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val articleImageView: ImageView = itemView.findViewById<ImageView>(R.id.article_image)
    private val titleTextView: TextView = itemView.findViewById<TextView>(R.id.article_title)

    private var currentPage: WikiPage? = null

    fun updateWithPage(page: WikiPage){
        currentPage = page

        titleTextView.text = page.title

        // load image lazily with picasso
        if(page.thumbnail != null)
            Picasso.with(itemView.context).load(page.thumbnail!!.source).into(articleImageView)
    }
}

So here we create a ViewHolder subclass called CardHolder that references its ImageView and TextView that can be initialized right away by querying the passed in itemView property from the constructor. We also add a convenience function to update the ViewHolder and it’s included views with a given WikiPage model (this model is what represents an article from Wikipedia and looks something like this:

WikiPage.kt

class WikiPage {
    var pageid: Int? = null
    var title: String? = null
    var fullurl: String? = null
    var thumbnail: WikiThumbnail? = null
}

WikiThumbnail

class WikiThumbnail {
    val source: String? = null
}

This model is the datatype our Adapter will reference as well.

Lastly, I added a quick reference the the Picasso Library from Square in order to load an image from the thumbnail url into our ImageView.

Creating an Adapter

Now the last thing we need to do is connect our ViewHolder and Data to our RecyclerView by creating our Adapter. Here’s what that will look like:

ArticleCardRecyclerAdapter.kt

class ArticleCardRecyclerAdapter() : RecyclerView.Adapter<CardHolder>() {
    val currentResults: ArrayList<WikiPage> = ArrayList<WikiPage>()

    override fun getItemCount(): Int {
        return currentResults.size
    }

    override fun onBindViewHolder(holder: CardHolder?, position: Int) {
        var page = currentResults[position]
        holder?.updateWithPage(page)
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): CardHolder {
        var cardItem = LayoutInflater.from(parent?.context).inflate(R.layout.article_card_item, parent, false)
        return CardHolder(cardItem)
    }
}

You can see our ArticleCardRecyclerAdapter inherits from the RecyclerView.Adapter and passes in our CardHolder view holder we just created as the type of ViewHolder. This allows for our required override functions to use that CardHolder as its type.

The adapter requires only 3 functions to be overridden, but there are also other functions available to override.
The three required are:
– getItemCount() to return the number of items the RecyclerView will have within it
– onBindViewHolder() to bind the data of a given position to the CardHolder. Here is where we call that updateWithPage function we created in our CardHolder class.
– onCreateViewHolder() to create the initial view holder by inflating a given layout file (which we use to inflate the article_card_item.xml file.

Now that we have our adapter, we can go and update our MainActivity:

MainActivity.kt

class MainActivity : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val adapter = ArticleCardRecyclerAdapter()
        adapter.currentResults = ArrayList<WikiPage>()..... // you should load your cards here! 
        article_recycler_view.adapter = adapter
        article_recycler_view.layoutManager = LinearLayoutManager(context)
        // note that in Java we would have to call .setLayoutManager, but Kotlin auto-maps this to a property
     }
}

Now you should be able to run and see your list of cards if you’ve loaded a collection of WikiPage models into your currentResults property on the adapter.

Now we can also change the layoutManager property of our recycler to something that might fit our smaller cards a bit better such as the StaggeredGridLayoutManager.

article_recycler_view.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)

This means we want 2 columns and we want to stack the cards vertically within those columns. If the direction is switched to HORIZONTAL then the number before it will represent the number of rows instead of columns.

Then with that we can have a view like this!

Screen Shot 2018-03-01 at 2.53.02 PM

And that’s pretty cool!


Also, let me know what else you’d like to learn about with Android and Kotlin! Either drop a comment here or tweet at me @Suave_Pirate!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.