Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
RyotaMurohoshi
July 14, 2014
Technology
0
33
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
2014/07/04 かわいいKotlin勉強会で行った発表の資料です
※ 元々はSlideShareで公開していた資料です。
RyotaMurohoshi
July 14, 2014
Tweet
Share
More Decks by RyotaMurohoshi
See All by RyotaMurohoshi
Tilemapのアップデートについて
ryotamurohoshi
0
72
Unityの合同同人誌や合同商業誌を書いてる僕は感想やレビューや評価が欲しい
ryotamurohoshi
0
580
Unity 2021.1での Unityパッケージの名称変更について
ryotamurohoshi
0
800
Odin Validationはいいぞ!
ryotamurohoshi
2
1k
Tilemapはいいぞ!2020 〜すごいぞ、プロジェクト専用拡張Brush〜
ryotamurohoshi
0
2.5k
Unityでも、新しいC#
ryotamurohoshi
0
1.4k
Riderはいいぞ!
ryotamurohoshi
1
3.7k
Riderのススメ〜俺はRiderここが好き〜
ryotamurohoshi
1
2.7k
Unity開発者に伝えたい.NETのこと
ryotamurohoshi
4
38k
Other Decks in Technology
See All in Technology
AIエージェント時代に備える AWS Organizations とアカウント設計
kossykinto
3
810
Oracle Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
4
1.2k
PMBOK第8版は第7版から何が変わったのか(PMBOK第8版概要解説) / 20260304 Takeshi Watarai
shift_evolve
PRO
0
200
Evolution of Claude Code & How to use features
oikon48
1
590
身体を持ったパーソナルAIエージェントの 可能性を探る開発
yokomachi
1
100
IBM Bobを使って、PostgreSQLのToDoアプリをDb2へ変換してみよう/202603_Dojo_Bob
mayumihirano
1
320
[JAWSDAYS2026][D8]その起票、愛が足りてますか?AWSサポートを味方につける、技術的「ラブレター」の書き方
hirosys_
3
120
AIエージェント、 社内展開の前に知っておきたいこと
oracle4engineer
PRO
2
110
AI は "道具" から "同僚" へ 自律型 AI エージェントの最前線と、AI 時代の人材の在り方 / Colleague in the AI Era - Autonomous AI Seminar 2026 at Niigata
gawa
0
140
vLLM Community Meetup Tokyo #3 オープニングトーク
jpishikawa
0
320
[2026-03-07]あの日諦めたスクラムの答えを僕達はまだ探している。〜守ることと、諦めることと、それでも前に進むチームの話〜
tosite
0
190
堅牢.py#2 LT資料
t3tra
0
130
Featured
See All Featured
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
390
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
110
My Coaching Mixtape
mlcsv
0
69
How to Think Like a Performance Engineer
csswizardry
28
2.5k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.4k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
120
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
110
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
310
Transcript
໌͔Βͪΐͬͱ KotlinͰAndroid͕ॻ͖ͨ͘ͳΔ(͔͠Εͳ͍ʁ) SAMมͱ֦ுؔ ɹ ྄ࣨଠ 2014/7/4(ۚ))ୈ2ճ)͔Θ͍͍Kotlinษڧձ)#jkug
ಥવͰ͕࣭͢Ͱ͢ʂ
Kotlinॻ͍ͨ͜ͱ͋Δํʁ
ʮKotlin'ॻ͍ͨ͜ͱͳ͍ʯ ͬͯΠϕϯτϖʔδʹॻ͍͚ͨΕͲ ຊॻ͍ͨ͜ͱ͋Δํʁ
AndroidΞϓϦ ։ൃͨ͜͠ͱ͋Δํʁ
͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ
͓લͩΕΑ • ໊લ":"྄ࣨଠ • ࣄ":"AndroidΞϓϦ։ൃ(Java)ɺUnityήʔϜ։ൃ(C#) • Twi6er":"@RyotaMurohoshi • ߘઌ":"h6p:/ /qiita.com/RyotaMurohoshi
• ڵຯ":"Kotlin,"Groovy,"C#,"Unity,"SonyͷWearable"Device
AndroidΞϓϦΛJavaͰ։ൃ͍ͯͯ͠ɺ ʮͳΜͰ͜Μͳʹͳίʔυ͕ඞཁͳΜͩʂʯ ͬͯΠϥͬͱ͢Δ͜ͱ͋Γ·ͤΜ͔ʁ
ࢲ͋Γ·͢ʂ C#ΛۀͰ͍࢝ΊͨΓͨ͠Γɺ GroovyΛ΄Μͷͪΐͬͱษڧͨ͠Βɺ ʮͳΜͰJavaɺʓʓͰ͖ͳ͍ͷʔʂʯ ͬͯɺΠϥοͱͳΓ·ͨ͠
ͦ͜ͰKotlinͰ͢Ͷʂ
໌͔Βͪΐͬͱ KotlinͰAndroid͕ॻ͖ͨ͘ͳΔ(͔͠Εͳ͍ʁ) SAMมͱ֦ுؔ ͱͯ͠ࠓLT͠·͢ʂ
͍Βͬͱ͢Δͳίʔυ̍ button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {
Log.v(TAG, "clicked"); } }); ͲΜͳAndroidೖॻʹࡌ͍ͬͯΔɺΞΫςΟϏςΟͰΑ͘ΈΔίʔυ KotlinͰॻ͍ͨͭͱൺΔͱɺͳͷ͕Ұྎવʂ
Kotlinͩͱ͖ͬ͢Γ button.setOnClickListener { Log.v(TAG, "clicked") }
JavaɺKotlinͦΕͧΕͷΫϦοΫϦεφʔ Kotlin button.setOnClickListener { Log.v(TAG, "clicked") } Java button.setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { Log.v(TAG, "clicked!"); } });
ߦ͕͘ͳͬͨ͜ͱͰͳ͘ɺ ʮͳ෦ॻ͘ඞཁ͕ͳ͘ ຊ࣭తͳ͜ͱ͚ͩॻ͚Α͘ͳͬͨʯ ͱ͍͏ͷ͕ϛι
JavaͷίʔυΛ͏ҰݟͯΈ·͠ΐ͏ button.setOnClickListener(new View.OnClickListener() { // newҎ߱ຊ࣭͡Όͳ͍ @Override // <- ຊ࣭͡Όͳ͍
public void onClick(View v) { // <- ຊ࣭͡Όͳ͍ Log.v(TAG, "clicked!"); } // <- ຊ࣭͡Όͳ͍ }); // <- ຊ࣭͡Όͳ͍ Javaຊ࣭͡Όͳ͍෦͕ଟ͍ɻKotlinຊ࣭ͷΈΛهड़͢Ε͍͍ Kotlinͳͥ͋Μͳهड़͕Ͱ͖Δͷ͔ʁ
Single'Abstract'Method'Conversions SAMม h"p:/ /blog.jetbrains.com/kotlin/2013/08/kotlin;m6;is;here/
SAM$ΠϯλʔϑΣʔε Ұͭͷ(Single))ந(Abstract))ϝιου(Method) ΛͭΠϯλʔϑΣʔε • Runnable):)void)run() • View.OnClickListener):)void)onClick(View)v) • Response.Listener<T>):)void)onResponse(T)response)) ͳͲɺଞʹͨ͘͞Μ
SAMม ؔϦςϥϧ!">!SAMΠϯλʔϑΣʔε!ͳม KotlinͰɺSAMΠϯλʔϑΣʔεΛҾʹͱΔϝιουͰɺ Ҿͷܕͱॱংͦͯ͠ฦܕ͕Ұக͢ΔؔϦςϥϧΛ͢ͱ ΠϯλʔϑΣʔεʹมͯ͘͠ΕΔ SAMΠϯλʔϑΣʔε͕ඞཁͳॴɺؔϦςϥϧͰεοΩϦʂ
SAMมͰ͖Δྫ button.setOnClickListener( { (v : View): Unit -> Log.v(TAG, "clicked")
}) button.setOnClickListener( { v -> Log.v(TAG, "clicked")}) button.setOnClickListener{ v -> Log.v(TAG, "clicked") } button.setOnClickListener{ Log.v(TAG, "clicked") } val listener : (View) -> Unit = {v -> Log.v(TAG, "clicked") } //or val listener : (View) -> Unit = { Log.v(TAG, "click") } //or val listener = { (v : View) : Unit -> Log.v(TAG, "clicked") } button.setOnClickListener(listener)
SAMมͰ͖ͳ͍ྫ // ԼهίϯύΠϧΤϥʔ // Type mismatch val listener : View.OnClickListener
= { (v : View) : Unit -> Log.v(TAG, "clicked") } // Լه࣮ߦ࣌Τϥʔ // java.lang.ClassCastException val listener = { (v : View) : Unit -> Log.v(TAG, "clicked") } as View.OnClickListener ҾʹؔϦςϥϧΛ͞ͳ͍ͱ͍͚ͳ͍
SAMมͰແବίʔυΛແͤ͘·͢Ͷʂ ͏Ұྫ VolleyͷStringRequest
VolleyͷStringRequest0Java൛ StringRequest request = new StringRequest( "https://www.google.co.jp/", new Response.Listener<String>() {
@Override public void onResponse(String response) { Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Toast.makeText(getApplicationContext(), "onErrorResponse", Toast.LENGTH_LONG).show(); } } ); ແବͳ෦͕ଟ͘ɺॎʹ͍ɽɽɽ
VolleyͷStringRequest0Kotlin൛ val request = StringRequest( url = "https://www.google.co.jp/", listener =
{ response -> Toast.makeText(this, response, Toast.LENGTH_LONG).show() }, errorListener = { volleyError -> Toast.makeText(this, "onErrorResponse", Toast.LENGTH_LONG).show() } ); ܕύϥʔϝʔλ͕͋ΔΠϯλʔϑΣʔεSAMมՄೳ ໊લ͖ҾͰՄಡੑΞοϓ
ͪΐͬͱGroovyΈͯΈ·͠ΐ͏ GroovySAMม͕͑ΔΑ͏Ͱ͢ɻ button.setOnClickListener { v -> Toas.makeText(this, "click", Toast.LENGTH_LONG).show() }
Groovy&2.2͔Βasԋࢉࢠ͕͍Βͳ͘ͳͬͨͦ͏Ͱ͢ɻ h"p:/ /groovy.codehaus.org/Groovy+2.2+release+notes
ͪΐͬͱGroovyΈͯΈ·͠ΐ͏ SAMΠϯλʔϑΣʔε͚ͩͰͳ͘ɺෳϝιουΛ࣋ͭΠϯλʔϑΣʔε Map+Ϋϩʔδϟʔ+asԋࢉࢠͰ͜Μͳײ͡ʹʂ viewPager.setOnPageChangeListener ([ onPageScrollStateChanged: { state -> Log.v(TAG,
state) }, onPageScrolled : { position, positionOffset, positionOffsetPixels -> /*ུ*/ }, onPageSelected : { position -> Log.v(TAG, position) } ] as ViewPager.OnPageChangeListener) h"p:/ /groovy.codehaus.org/Groovy+way+to+implement+interfaces
࣮AndroidStudioͱIntelliJͩͱ Ұ͚ͭͩϝιουΛ࣮ͨ͠ಗ໊Ϋϥε͕͍͍ײ͡ʹʂ(SAMܕ) button.setOnClickListener((v) -> {Log.v(TAG, "clicked");}); IDE্Ͱ͍͍ײ͡ͰંΓ·Εͯ·͕͢ɺ githubͱ͔ͰίʔυϦϏϡʔ͢Δͱ͖ɺ ΄Β·Εͳ͍͠ɽɽɽ h"p:/
/qiita.com/RyotaMurohoshi/items/0ce799c747d91756131a
Ҏ্ SAMมͰͨ͠ɻ
͍Βͬͱ͢Δͳίʔυ̎ ImageView imageView = (ImageView)findViewById(R.id.image_view); ͲΜͳAndroidೖॻʹࡌ͍ͬͯΔɺΞΫςΟϏςΟͰΑ͘ΈΔίʔυ ͚ΕͲʮImageViewʯͬͯͳΜͰ2ճॻ͘ඞཁ͋ΔΜʁܕਪͯ͘͠Ε͍͍ͯ͡ΌΜʂ
ͱΓ͋͑ͣܧঝ͠·͢ʁ Ac#vityΛܧঝͨ͠ΫϥεBaseAc#vityʹͯɺ͜Μͳϝιουఆٛ͢Εɺ public <T extends View> T findById(int viewId) {
return (T)findViewById(viewId); } BaseAc'vityΛߋʹܧঝͨ͠ΫϥεͰɺ͜Μͳײ͡ͰΩϟετෆཁʹͳΓ·͢Ͷ ImageView imageView = findById(R.id.image_view);
͚Ͳܧঝͬͯ • ܧঝΉ͍ͣ • ʮܧঝ͕ڐ͞ΕΔͷখֶੜ·ͰͩΑͶʯɺͩͱɽɽɽ • Ac$vityͷαϒΫϥε͍͔ͭ͋͘Δ͚Ͳɺશ෦ʹߋʹαϒΫϥε ࡞ͬͯϝιουఆٛ͢Δʁ ͪΐͬͱͳ͍͔ͳɽɽɽ
ͯ͞Ͳ͏͠·͠ΐ͏ʁ • ͳهड़͕සൃͨ͠ΓɺΑ͘͏ॲཧ͕͋Δ • Ac$vityͱ͔ʹɺϝιουΛՃ͍ͨ͠ʂ • ͚Ͳܧঝͨ͘͠ͳ͍)or)Ͱ͖ͳ͍
Extension)Funcitons ֦ுؔ h"p:/ /confluence.jetbrains.com/display/Kotlin/Extension+func=ons
Extension)Funcitons(֦ுؔ)ͱ • ܧঝͤͣʹϝιουΛՃͰ͖Δ" • ܧঝېࢭͳΫϥεʹϝιουΛՃͰ͖Δ • privateͳϝϯόʹΞΫηεͰ͖ͳ͍ • ϝιουΛΦʔόʔϥΠυͰ͖ͳ͍
Extension)Func-onsͷྫ)ఆٛଆ extensions.ktʹͯ package com.mrstar.extensions import android.app.Activity import android.view.View fun <T
: View> Activity.findById (id : Int) : T = findViewById(id) as T
Extension)Func-onsͷྫ)ར༻ଆ package com.mrstar.android_with_kotlin // ུ import com.mrstar.extensions.findById // <-
public class MainActivity() : FragmentActivity() { // <- protected override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView: ImageView = findById (R.id.image_view) // <- } }
• fun$ClassName.methodName(hoge$:$Hoge)$:$Fuga"Έ͍ͨͳײ͡Ͱ ϝιουΛఆٛ͠·͢ • ఆ֦ٛͨ͠ுϝιουΛimport͠·͢ • ͦ͏͢Δͱී௨ͷϝιουͷΑ͏ʹ͑·͢ • ͜ͷྫͩͱAc+vityͷαϒΫϥε͚ͩͰͳ͘ɺ FragmentAc+vityɺAc+onBarAc+vityɺଞͷαϒΫϥεͰ͑
·͢(ܧঝͰఆٛ͢ΔͳΒɺ֤Ϋϥεʹϝιουఆ͕ٛඞཁ)
Extension)Func-onsΛ͑ɽɽɽ • ܧঝ͠ͳͯ͘ϝιουΛՃͰ͖·͢Ͷ • ͨ͘͞ΜͷΫϥεʹϝιουΛՃ͠ͳ͍͍ͯ͘Ͱ͢Ͷ • ࣗ࡞ͷϝιουͰͳهड़ΛεοΩϦͰ͖·͢Ͷʂ
ͪΐͬͱC#ΈͯΈ·͠ΐ͏ C#ʹ֦ுؔͱಉ͡Α͏ͳ֦ுϝιου͕͋Γ·͢ɻ // ఆٛଆ public static class StringExtensions { public
static string Decorate(this string str, string symbol) { return string.Format("{0}{1}{2}", symbol, str, symbol); } } //ར༻ଆ string decoratedMessage = "Hello!".Decorate("===") ͜Μͳײ͡Ͱɺsta$cͳΫϥεʹsta$cͳϝιουͱ֦ͯ͠ுϝιουΛఆٛ͠·͢ɻ
ͪΐͬͱC#ΈͯΈ·͠ΐ͏ C# • JavaͷpackageΞΫηεͷΑ͏ͳɺϝϯόΛಉ໊͡લۭ͚ؒͩʹ ެ։͢Δͱ͍͏੍ݶ͕ͳ͍ • privateͰsta.cͳೖΕࢠͷΫϥε࡞ΕΔ • ͕↑ͳΫϥεͰ֦ுϝιουΛఆٛͰ͖ͳ͍ ͜ͷΫϥεʹ͚ͩɺ͜ͷ໊લۭؒͰ͚ͩ͑Δͱ͍͏֦ுϝιουΛఆٛͰ͖ͳ͍ʂ
ҰํKotlinͰ • packageʹͦͷ໊લۭؒͱͦͷαϒ໊લۭؒݶఆͰ • ΫϥεʹprivateΞΫηεϨϕϧͰ • ؔʹϩʔΧϧؔͱͯ͠ɺϩʔΧϧείʔϓͰ Kotlinͩͱ֦ுؔΛఆٛͰ͖Δʂ
Ҏ্ ֦ுؔͰͨ͠ɻ
࣭͋Γ·͔͢ʁ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ ɹ SAMมʹ͍ͭͯ(Qiita) h"p:/ /qiita.com/RyotaMurohoshi