RecycleViewを書いてみよう
RecycleView全然手出ししてなかったのでやってみようという単純かつおばかな理由でKotlinで実装する事にしました。以下資料
Developer http://developer.android.com/intl/ja/reference/android/support/v7/widget/RecyclerView.html
チュートリアル http://developer.android.com/intl/ja/training/material/lists-cards.html
Googleのサンプル https://github.com/googlesamples/android-RecyclerView
や〜Googleのデベロッパーは英語が簡単でいいな〜、This is a Pen〜I am Pen〜レベルの英語。Appleのデベロッパー行った時英語の難しさで(T . T)泣きましたもん。基本的にはlistViewみたいにAdapter作ってxmlはめればいいんですが多少注意が必要です
AdapterでfindViewByIdやListener当てる時はonBindViewHolderメソッドじゃなくてViewHolderのコンストラクタで行え。 http://androidessence.com/recyclerview-vs-listview/
RecyclerView.LayoutManagerはちゃんと設定 https://github.com/googlesamples/android-RecyclerView/blob/master/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java
調べれば調べるほど「普通のやつはListViewでいいんじゃね?」と思いました。 http://sys1yagi.hatenablog.com/entry/2015/01/09/090000
Kotlinで実践的にAndroid実装する時のポイント
Kotlinは覚えやすいけど当然Javaと違うので幾つか注意点抑えとかないとです
Nullの扱い方
NullSaftyな言語なんで当然扱い方にルールがあります。@yy_yankさんのこのページが大変参考になりました。Swiftでもこういうページが欲しかった
【Nullいことしてんじゃねぇ】声に出して読みたいKotlin http://yyyank.blogspot.jp/2014/12/nullkotlin-ktac2014.html#Pbp3acE.twitter_tweet_box_count
・Nullじゃなけりゃ手短に(If not null shorthand)
・Null如何にせよ手短に(If not null and else shorthand)
・Nullじゃなけりゃ、やっちまえ(Execute if not null)
・ユー、whenで返しちゃいなよ(Return on when statement)
・ユー、ifで返しちゃいなよ(Return on if statement)
・ユー、tryブロックごと返しちゃいなよ(Return on try catch block)
・非Nullだってばよ(Not-Null)
・マップにお任せ(Storing Properties in a Map)
・Null安全(Null Safety)
・安全なキャスト(Safe Casts)
・安全呼び出し(Safe Calls)
コンストラクタ
Kotlinのコンストラクタはめちゃ簡単、
class CustomAdapter(cardview : Array<card_View>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>(){ protected val mCardView : Array<card_View> = cardview
セカンダリ及びsuperつきだとこんな感じ
class ViewHolder : RecyclerView.ViewHolder { constructor(v: View):super(v) {} }
ちょっと面食らうくらいシンプルなんで逆に迷いました。JavaからKotlinで一番面食らうかも。詳しくは以下のサイトで解説されているのでご一読をhttp://dev.classmethod.jp/smartphone/android-kotlin-introduction-04/
スコープ関数
Kotlinに用意されてるパッケージの中でインスタンスをいじる時に用意される便利関数。エバンジェリスト@ngsw_taroさんの解説が詳しい。
- Kotlin スコープ関数 用途まとめ http://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e
デベロッパーのサイトでもスコープ関数以外もあるまとまった解説がありました。
- Package kotlin https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/
詰まった時はAndroidStudioのコード補完が教えてくれます。コード補完でメソッド名にあたりをつけたらググってデベロッパーなり優秀な方がの記事で調べてます。実装の段階になればNullチェックに使うlet、インスタンスをいじるapplyあたりは必ず使う感じです
実装コード見本
以上の点を抑えつつ実装に入ります。今回は例としてRecycleViewのAdapterクラスのコードを晒してみます
class CustomAdapter(cardview : Array<card_View>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>(){ protected val mCardView : Array<card_View> = cardview class ViewHolder : RecyclerView.ViewHolder { constructor(v: View):super(v) { //SAM変換がもろにきいてます v.setOnClickListener { print("Element " + getAdapterPosition() + " clicked.") } } //KotlinExtentionを使ってるのでfindViewByIdはなし } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? { val v : View = LayoutInflater.from(parent.context).inflate(R.layout.recycle_card,parent,false) return ViewHolder(v) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { Log.d("test",mCardView[position].card_title) //setter,getterは書かなくてもインスタンスについてくる holder.itemView.card_title.text = mCardView[position].card_title holder.itemView.caption1.text = mCardView[position].caption1 holder.itemView.caption2.text = mCardView[position].caption2 } override fun getItemCount(): Int { return mCardView.count() } }
コード少ない!軽いプロジェクト1個書いたんですが体感でコード量は2/3に感じます。同じ内容をJavaでもかいてみます
public class CustomAdapterJava extends RecyclerView.Adapter<CustomAdapterJava.ViewHolder>{ private ArrayList<card_View> mCardview = null; private static final String TAG = "CustomAdapterJava"; public CustomAdapterJava(ArrayList<card_View> cardview){ mCardview = cardview; } public static class ViewHolder extends RecyclerView.ViewHolder { private TextView mTitle = null; private TextView mcaption1 = null; private TextView mcaption2 = null; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "Element " + getAdapterPosition() + " clicked."); } }); //以下三行はDataBindingしてればいらない mTitle = (TextView)itemView.findViewById(R.id.card_title); mcaption1 = (TextView)itemView.findViewById(R.id.caption1); mcaption2 = (TextView)itemView.findViewById(R.id.caption2); } public TextView getmTitle(){return mTitle;} public TextView getMcaption1(){return mcaption1;} public TextView getMcaption2(){return mcaption2;} } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycle_card, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.getmTitle().setText(mCardview.get(position).getCard_title()); holder.getMcaption1().setText(mCardview.get(position).getCaption1()); holder.getMcaption2().setText(mCardview.get(position).getCaption2()); } @Override public int getItemCount() { return mCardview.size(); } }
setter,getterいらないだけでもかなり可読性違うと思います。以上AndroidをKotlinで実装する際の最初のポイントっぽいのをまとめてみました エミュレーターで実行したらこんな感じです。