最近人気のKotlinでViewPagerアプリを作ってみた
こんにちは。今年の夏からAndroidエンジニアとしてPairsのAndroid版を開発しているインターンの仙波です。
本日は最近Androidの新しい言語として人気を集めている「Kotlin」について書こうと思います。
Kotlinでサンプルアプリ
エウレカでは、入社する前にちょっとした課題が出されます。Androidの職種で入社した私の場合、「Dribbble」というデザインサイトのAPIを利用して簡単なアプリを作成するという課題でした。
そこで、今回はその課題をJavaからKotlinに変換したアプリを作成しました。
作成したプロジェクトはGitHubに公開しているので、よろしければご覧になってみてください。
https://github.com/TakuSemba/DribbbleSampleApp
サンプルアプリの実行手順
1.KotlinのPluginをインストール
2.DribbbleのAPIkeyを取得
ここで紹介しているサンプルアプリは、DribbbleのAPIを使用しているため、開発者アカウントを登録し、APIkeyを取得する必要が有ります。
お手数ですが、こちらのDribbbleサイトからRegistorApplicationへ進み、アカウントの登録を行ってください。
その後ClientAccessTokenが取得できると思います。
3. Tokenをコードに挿入
以下のコードに先ほど取得したTokenを入れ込んでください。
以下のGif動画のようなアプリを端末上で確認することができると思います。
このようなアプリをいつも作成しております。
最近では、電車で寝る人(私)のために、場所を登録する目覚ましアプリをリリースしました。
https://play.google.com/store/apps/details?id=com.takusemba.mapme
それでは、早速Kotlinについて書きたいと思います。
そもそもKotlinとは?
Kotlinとは、IntelliJや各種IDEでおなじみのJetBrains社が中心となって開発を進めているJVM上で動作する言語です。
JVM上で動作する言語は他にClojure、Groovy、Scalaなどもありますが、Kotlinは自由度も高く、文法もシンプルで簡単なプロジェクトやアプリ開発に適した言語です。
導入方法
では、どうやってKotilinでの開発を始めるのか。非常に簡単でKotlinはJetBrains社が開発していることもあり、IntelliJのプラグインとしてKotilinは提供されています。
AndroidStudioを使用している方もIntelliJと同様にしてKotlinのプラグインをインストールするだけでKotlinの開発を始めることができます。
参考 URL
Getting Started with IntelliJ IDEA
Getting started with Android and Kotlin
KotlinのPlaygroundもWeb上に存在しているので、Kotlinに触れてみたい方は下記のリンクから試してみてください。
Try Kotlin
それでは、Kotlinの魅力を説明していきたいと思います。
魅力1:コード量を削減できる
アクセサ (Getter, Setter) がいらない!
Kotlinでは、GetterやSetterのアクセサが内部で自動生成されるため、Javaのように一つ一つ書く必要がありません。
※Javaは慣例として、カプセル化を推奨しているためpublicなインスタンス変数を避けるべきとされています。
// Shot class on Java
public class Shot {
private String title = ""; public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} // Something...
}// Shot class on Kotlin
public class Shot {
public var title: String = "" // Something...
}
インスタンス変数を直接参照しにいくように見えますが、アクセサが自動生成され、変数にアクセスする場合は全てアクセサを経由することになります。
Viewの参照がすっきりすぎる
Kotlinでは、Kotlin Android ExtensionsというPluginがあり、これを使うとすっきり書くことが可能になります。
通常、JavaでViewを参照すると、以下のようになると思います。
// Java
TextView textView = (TextView) findViewById(R.id.text_view);
textView.setText("Hello World");
これをKotlinに置き換えると
// Kotlin
text_view.setText("Hello World");
となり、非常に簡潔に書くことができます!
Listenerのセットが簡単
Javaでリスナーをセットすると、以下のようになると思います。
// Java
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG "button clicked !!");
}
});
Kotlinでは、抽象メソッドを唯一つもつインタフェースのオブジェクトに対して、以下のように関数リテラルとして表現し、引数として渡すことが可能です。
// Kotlin
button.setOnClickListener { Log.v(TAG, "button clicked !!") }
魅力2:ぬるぽを気にしなくて良い!
Javaでコーディングしているときに気をつけなければいけないのが NullPointerException
(通称:ぬるぽ) だと思います。Kotlinを使用するとぬるぽの発生リスクを最大限に減らすことができます。
コンパイル時エラー
理由はKotlinコード内にぬるぽが発生する箇所をコンパイル時にエラーとして吐き出すからです。そのため、Javaと違い実行時にエラーとなってクラッシュすることがありません。(明示的にNullPointerExceptionを発生させる場合は別)
非null型とnull許容型
Kotlinではnullを保持できる変数(null許容型)とnullを保持できない変数(非null型)の二種類が存在します。
// 非null型
var a : String = "abc"
// a = null // nullは代入することができない。
val l = a.length()// null許容型
var a : String? = "abc"
a = null
val l = a.length() // aがnullになる可能性があるためコンパイルエラー。
では、null許容型への代入はどのようにするのか。
// null許容型
var a : String? = "abc"
a = null
val l = a?.length ?: -1
このようにすると、nullでない時にはa.lengthを、nullの場合には-1を返すことになります。
魅力3:Javaとの互換性100%
KotlinはJVM上で動作する言語のため、Javaのコードと共存することができますし、Javaのライブラリをそのまま使用することもできます。
例として、Pairsでも使われているretrofitをJavaとKotlinで適用する方法を説明します。まずはJavaからです。
// Interfaceを定義
public interface ShotApi {
@GET("/shots/?access_token=" + ACCESS_TOKEN + "&per_page=24")
void fetchShots(
@Query("list") String type,
Callback<List<Shot>> callback
);
}// エンドポイントやConverterを実装
public class RestClient {
public static RestAdapter getRestAdapter() {
return new RestAdapter.Builder()
.setEndpoint("https://api.dribbble.com/v1/")
.setConverter(new GsonConverter(new Gson()))
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
}
}// APIリクエスト
RestClient.getRestAdapter()
.create(ShotApi.class)
.fetchShots(type.getKey(), new Callback<List<Shot>>() {
@Override
public void success(List<Shot> shots, Response response) {
// Do something
}
@Override
public void failure(RetrofitError error) {
Log.d(TAG, "onError: " + error.getMessage());
}
});
}
これをKotlinで適用すると
// Interfaceを定義
interface ShotApi {
@GET("/shots/?access_token=$ACCESS_TOKEN&per_page=24")
fun fetchShots(
@Query("list") type: String,
callback: Callback<List<Shot>>
)
}// エンドポイントやConverterを実装
object RestClient {
val restAdapter: RestAdapter
get() = RestAdapter
.Builder()
.setEndpoint("https://api.dribbble.com/v1/")
.setConverter(GsonConverter(Gson()))
.setLogLevel(RestAdapter.LogLevel.FULL)
.build()
}// APIリクエスト
RestClient.restAdapter
.create<ShotApi>(ShotApi::class.java)
.fetchShots(type.key, object : Callback<List<Shot>> {
override fun success(
shots: List<Shot>,
response: Response
) {
// Do something
}
override fun failure(error: RetrofitError) {
Log.d(TAG, "onError: " + error.message)
}
}
)
このように、Javaで書かれたライブラリであっても簡単にkotlin内で使用することができます。
魅力4:it(それ!?)
私が最初見たときに「なんだこれ??」と思ったのですが、引数が一つの時はitだけで定義することができます。
例えば以下のような感じになります。
// Kotlin
fun main(args: Array<String>) {
var A = (1..3).map { it * 2 }
print(A) // [2, 4, 6]
}
最後に
Kotlinでサンプルアプリを作ってみて、簡単なアプリであればKotlinで書くのも全然ありだと思いました。しかし、まだドキュメントやコミュニティーなどが成熟していない点もあり、今すぐに全てKotlinに移行するのはまだ時期尚早かなと思っています。
今後Kotlinがどのように変化していくのか楽しみです!
KotlinサンプルApp
https://github.com/TakuSemba/DribbbleSampleApp
場所で起こす目覚まし (MapMe)
https://play.google.com/store/apps/details?id=com.takusemba.mapme