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
Ankoに はさんで はさまれて
Search
yamm800
July 10, 2016
Technology
0
320
Ankoに はさんで はさまれて
第一回 Kansai.kt 発表資料
AnkoとはKotlinのDSLでAndroidのUIを組み立てることができるJetBrains公式のライブラリです。
yamm800
July 10, 2016
Tweet
Share
More Decks by yamm800
See All by yamm800
Ankoに はさんで はさまれて 発表者ノート付き
yamm800
0
54
Other Decks in Technology
See All in Technology
20251014_Pythonを実務で徹底的に使いこなした話
ippei0923
0
210
incident_commander_demaecan__1_.pdf
demaecan
0
160
[Codex Meetup Japan #1] Codex-Powered Mobile Apps Development
korodroid
2
960
ソースを読むプロセスの例
sat
PRO
15
9.1k
アイテムレビュー機能導入からの学びと改善
zozotech
PRO
0
190
防災デジタル分野での官民共創の取り組み (2)DIT/CCとD-CERTについて
ditccsugii
0
310
ソフトウェアエンジニアの生成AI活用と、これから
lycorptech_jp
PRO
0
380
初めてのDatabricks Apps開発
taka_aki
1
110
OAuthからOIDCへ ― 認可の仕組みが認証に拡張されるまで
yamatai1212
0
130
【Kaigi on Rails 事後勉強会LT】MeはどうしてGirlsに? 私とRubyを繋いだRail(s)
joyfrommasara
0
270
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
12
80k
データ戦略部門 紹介資料
sansan33
PRO
1
3.8k
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
34
2.3k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
GitHub's CSS Performance
jonrohan
1032
470k
Rails Girls Zürich Keynote
gr2m
95
14k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
Six Lessons from altMBA
skipperchong
29
4k
Unsuck your backbone
ammeep
671
58k
Faster Mobile Websites
deanohume
310
31k
GraphQLとの向き合い方2022年版
quramy
49
14k
Docker and Python
trallard
46
3.6k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Statistics for Hackers
jakevdp
799
220k
Transcript
"OLPʹ͞ΜͰ͞·Εͯ גࣜձࣾφνϡϥϧελΠϧ ࢁޱஐߦ
ࣗݾհ w ࢁޱஐߦ w גࣜձࣾφνϡϥϧελΠϧॴଐ
࡞͍ͬͯΔͷ w ϑΝογϣϯίʔσΟωʔτ ΞϓϦʮ8&"3ʯΛ࡞
w ͔͜͜Βຊ
"OLP w ,PUMJOͷ%4-Ͱ"OESPJEͷ6*ΛΈཱͯΔϥΠϒϥ Ϧ w +FU#SBJOTެࣜ w ·ͩόʔδϣϯ
"OLPͷϝϦοτ w 9.-Ͱͳ͍͜ͱʹΑΔϝϦοτ w 9.-Λύʔε͠ͳ͍͍ͯ͘ͷͰૣ͍ w pOE7JFX#Z*E͠ͳ͍͍ͯ͘ w ,PUMJOʹΑΔԸܙ w
ܕ҆શ w /VMM҆શ w ػೳ֦ு͕༰қ w ϥΠϒϥϦʹศརͳ͕ؔ༻ҙ͞Ε͍ͯΔ
ͪͳΈʹ1SFWJFXػೳ͍͍ͭͯ·͢
ͪͳΈʹ1SFWJFXػೳ͍͍ͭͯ·͢ ͍ͭͯ·͚͢Ͳ
όʔδϣϯͩͱ͏·͘ಈ͔ͳ͔ͬͨͷͰҙɻ ͳΒ͏·͘ಈ͖·ͨ͠
9.-Λࣗಈม͢Δπʔϧ͋Δ $PEF$POWFSUUP,PBO%4-
9.-Λࣗಈม͢Δπʔϧ͋Δ $PEF$POWFSUUP,PBO%4- "OLP͡Όͳͯ͘ ,PBOʹͳ͍ͬͯΔͷ͓͖ͯ͞
ෆຬ w %BUB#JOEJOHͱҰॹʹ͑ͳ͍ w %FMFHBUFE1SPQFSUJFTΛ͑ࣅͨΑ͏ͳ͜ͱ Ͱ͖Δ͚ΕͲͪΐͬͱ໘ w 1SFWJFXͰ9.-Ͱͷ5PPMTଐੑͷΑ͏ͳ͜ͱ͕Ͱ͖ ͳ͍ w
$POTUSBJOU-BZPVUͲ͏ͳΔ
͍͔ͨ
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) verticalLayout { val
name = editText() button("Say Hello") { // ボタンを押したらトーストを表示 onClick { ctx.toast("Hello, ${name.text}!") } } } } "DUJWJUZͷதͰ࡞Δྫ
class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) MyActivityUI().setContentView(this) } } class MyActivityUI : AnkoComponent<MyActivity> { override fun createView(ui: AnkoContext<MyActivity>) = with(ui) { verticalLayout { val name = editText() button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } } } ΫϥεΛ͚ͨྫ
class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) MyActivityUI().setContentView(this) } } class MyActivityUI : AnkoComponent<MyActivity> { override fun createView(ui: AnkoContext<MyActivity>) = with(ui) { verticalLayout { val name = editText() button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } } } ΫϥεΛ͚ͨྫ JOUFSGBDF"OLP$PNQPOFOU5\ GVODSFBUF7JFX VJ"OLP$POUFYU5 7JFX ^
class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) MyActivityUI().setContentView(this) } } class MyActivityUI : AnkoComponent<MyActivity> { override fun createView(ui: AnkoContext<MyActivity>) = with(ui) { verticalLayout { val name = editText() button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } } } ΫϥεΛ͚ͨྫ
class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) MyActivityUI().setContentView(this) } } class MyActivityUI : AnkoComponent<MyActivity> { override fun createView(ui: AnkoContext<MyActivity>) = with(ui) { verticalLayout { val name = editText() button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } } } ΫϥεΛ͚ͨྫ ΫϥεΛ͚ͯ1SFWJFXಈ͖·͢
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return UI { verticalLayout { val name = editText { } button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } }.view } 'SBHNFOUͰ͏ྫ
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return UI { verticalLayout { val name = editText { } button("Say Hello") { onClick { ctx.toast("Hello, ${name.text}!") } } } }.view } 6*\^WJFXͰ͞Ή 'SBHNFOUͰ͏ྫ
include<View>(R.layout.something) { backgroundColor = Color.RED } 9.-ΛJODMVEF
// 以下の2行を追加 (カスタムビューの中などで良い) // ViewManagerの拡張関数 inline fun ViewManager.customView(theme: Int
= 0) = customView(theme) {} inline fun ViewManager.customView(theme: Int = 0, init: CustomView.() -> Unit) = ankoView({ CustomView(it) }, theme, init) ΧελϜϏϡʔΛ"OLP%4-ͷதͰ͏
// 以下の2行を追加 (カスタムビューの中などで良い) // ViewManagerの拡張関数 inline fun ViewManager.customView(theme: Int
= 0) = customView(theme) {} inline fun ViewManager.customView(theme: Int = 0, init: CustomView.() -> Unit) = ankoView({ CustomView(it) }, theme, init) // これでカスタムビューをAnkoに はさめる frameLayout { customView { } } ΧελϜϏϡʔΛ"OLP%4-ͷதͰ͏
// 以下の2行を追加 (カスタムビューの中などで良い) // ViewManagerの拡張関数 inline fun ViewManager.customView(theme: Int
= 0) = customView(theme) {} inline fun ViewManager.customView(theme: Int = 0, init: CustomView.() -> Unit) = ankoView({ CustomView(it) }, theme, init) // これでカスタムビューをAnkoに はさめる // カスタムビューの中にも Ankoを はさめる frameLayout { customView { text = textView("Anko CustomView") } } ΧελϜϏϡʔΛ"OLP%4-ͷதͰ͏
relativeLayout { // 一意のidを生成 ids.xmlに指定しても良い var main_activity_text: Int = View.generateViewId()
textView = textView { id = main_activity_text } textView { text = "Bottom of R.id.main_activity_text" lparams { bottomOf(main_activity_text) } } } *%Λࢦఆͯ͠3FMBUJWF-BZPVUͰ͏
relativeLayout { // 一意のidを生成 ids.xmlに指定しても良い var main_activity_text: Int = View.generateViewId()
textView = textView { id = main_activity_text } textView { text = "Bottom of R.id.main_activity_text" lparams { bottomOf(main_activity_text) } } } *%Λࢦఆͯ͠3FMBUJWF-BZPVUͰ͏
relativeLayout { // 一意のidを生成 ids.xmlに指定しても良い var main_activity_text: Int = View.generateViewId()
textView = textView { id = main_activity_text } textView { text = "Bottom of R.id.main_activity_text" lparams { bottomOf(main_activity_text) } } } *%Λࢦఆͯ͠3FMBUJWF-BZPVUͰ͏
relativeLayout { // 一意のidを生成 ids.xmlに指定しても良い var main_activity_text: Int = View.generateViewId()
textView = textView { id = main_activity_text } textView { text = "Bottom of R.id.main_activity_text" lparams { bottomOf(main_activity_text) } } } *%Λࢦఆͯ͠3FMBUJWF-BZPVUͰ͏
// Toast toast(R.string.message) // アラートダイアログ alert("Hi, I'm Roy", "Have
you tried turning it off and on again?") { yesButton { toast("Oh…") } noButton {} }.show() // Activityの呼び出し startActivity<SomeOtherActivity>("id" to 5) ศརͳػೳ
// 非同期処理 doAsync { // 何か重い処理 // Acitivityがfinishしていたら呼ばれない
activityUiThreadWithContext { result.text = "Done" } } ศརͳػೳ
*NBHF7JFXͷ֦ுؔ fun ImageView.loadImage(imageUrl: String, error: Int) { Picasso.with(context).load(imageUrl).error(error).into(this) } //
Picassoを使ってイメージを読み込み imageView = imageView { loadImage("画像のURL", R.drawable.error) } ֦ுؔΛ༻͢Δ
*NBHF7JFXͷ֦ுؔ fun ImageView.loadImage(imageUrl: String, error: Int) { Picasso.with(context).load(imageUrl).error(error).into(this) } //
Picassoを使ってイメージを読み込み imageView = imageView { loadImage("画像のURL", R.drawable.error) } ֦ுؔΛ༻͢Δ ,PUMJOͷԸܙΛͦͷ··ड͚ΕΔײ͡Ͱྑ͍
͓ΘΓʹ w ,PUMJOͷΓ্͕͍ͬͯΔҹ
͓ΘΓʹ w "OLPͷͬͯ͋·Γฉ͔ͳ͍
͓ΘΓʹ w 2JJUBͰͷهࣄ݅ͱ͔ͩͬͨ͠
͓ΘΓʹ w "OLPͬͱʹͳΔͱ͍͍ͳʂ
͓ΘΓʹ w ͦΜͳΘ͚Ͱ
͓ΘΓʹ w "OLPͷ͞ΜͰ΄͍͠
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
͕࣌ؒ͋ͬͨΒΔ
Ϩγʔό͖ؔϦςϥϧ ֦ுؔ ΛҾʹऔΔ ֦ுϓϩύςΟ ͍͍ͩͨ͜ͷΜͷػೳͰ࣮ݱ Ͳ͏͍ͬͯΔͷ͔
͘Θ͘͜͠ͷ͋ͨΓΛࢀর ,PUMJO,PBOTͷ#VJMEFSTͷষಛʹ)UNMCVJMEFSTͷ ෦ %4-ͷྫ ,PUMJO"OESPJE"#SBTT5BDLT&YQFSJNFOU (PPHMFͷਓ͕ॻ͍ͨهࣄӳޠ Ͳ͏͍ͬͯΔͷ͔
class MyListViewAdapter(var context:Context) : BaseAdapter() { override fun getView(position:Int,
convertView: View?, parent: ViewGroup?):View? { var newConvertView:View? if (convertView == null) { var ui = MyListItemUI(getItem(position), position) newConvertView = ui.createView(context.UI { }) newConvertView.tag = ui }else { newConvertView = convertView var ui = newConvertView.tag as MyListItemUI ui.label?.text = "List item: " + position newConvertView.tag = ui } return newConvertView } } class MyListItemUI(var user:User?,var position:Int) : AnkoComponent<Context> { var label : TextView? = null override fun createView(ui: AnkoContext<Context>) = with(ui) { verticalLayout { label = textView { text ="List item: " + position } } } } -JTU7JFXͰ͏ྫ
DMBTT.Z"DUJWJUZ"QQ$PNQBU"DUJWJUZ \ MB[ZΛͬͨ΄͏͕͍͍͔ WBMVJ.BJO"DUJWJUZ6JCZMB[Z\ .BJO"DUJWJUZ6J ^ PWFSSJEFGVOPO$SFBUF TBWFE*OTUBODF4UBUF#VOEMF QFSTJTUFOU4UBUF1FSTJTUBCMF#VOEMF
\ TVQFSPO$SFBUF TBWFE*OTUBODF4UBUF QFSTJTUFOU4UBUF VJTFU$POUFOU7JFX UIJT VJUFYU7JFX UFYUl"1*͔Βͱ͖ͬͯͨͱ͔z ^ ^ DMBTT.Z"DUJWJUZ6*"OLP$PNQPOFOU.Z"DUJWJUZ\ WBSUFYU7JFX5FYU7JFX OVMM PWFSSJEFGVODSFBUF7JFX VJ"OLP$POUFYU.Z"DUJWJUZ XJUI VJ \ লུ ^ ^ ΫϥεΛ͚ͨྫ
DMBTT.Z"DUJWJUZ"QQ$PNQBU"DUJWJUZ \ MB[ZΛͬͨ΄͏͕͍͍͔ WBMVJ.BJO"DUJWJUZ6JCZMB[Z\ .BJO"DUJWJUZ6J ^ PWFSSJEFGVOPO$SFBUF TBWFE*OTUBODF4UBUF#VOEMF QFSTJTUFOU4UBUF1FSTJTUBCMF#VOEMF
\ TVQFSPO$SFBUF TBWFE*OTUBODF4UBUF QFSTJTUFOU4UBUF VJTFU$POUFOU7JFX UIJT VJUFYU7JFX UFYUl"1*͔Βͱ͖ͬͯͨͱ͔z ^ ^ DMBTT.Z"DUJWJUZ6*"OLP$PNQPOFOU.Z"DUJWJUZ\ WBSUFYU7JFX5FYU7JFX OVMM PWFSSJEFGVODSFBUF7JFX VJ"OLP$POUFYU.Z"DUJWJUZ XJUI VJ \ লུ ^ ^ ΫϥεΛ͚ͨྫ
DMBTT.Z"DUJWJUZ"QQ$PNQBU"DUJWJUZ \ MB[ZΛͬͨ΄͏͕͍͍͔ WBMVJ.BJO"DUJWJUZ6JCZMB[Z\ .BJO"DUJWJUZ6J ^ PWFSSJEFGVOPO$SFBUF TBWFE*OTUBODF4UBUF#VOEMF QFSTJTUFOU4UBUF1FSTJTUBCMF#VOEMF
\ TVQFSPO$SFBUF TBWFE*OTUBODF4UBUF QFSTJTUFOU4UBUF VJTFU$POUFOU7JFX UIJT VJUFYU7JFX UFYUl"1*͔Βͱ͖ͬͯͨͱ͔z ^ ^ DMBTT.Z"DUJWJUZ6*"OLP$PNQPOFOU.Z"DUJWJUZ\ WBSUFYU7JFX5FYU7JFX OVMM PWFSSJEFGVODSFBUF7JFX VJ"OLP$POUFYU.Z"DUJWJUZ XJUI VJ \ লུ ^ ^ ΫϥεΛ͚ͨྫ
DMBTT.Z"DUJWJUZ"QQ$PNQBU"DUJWJUZ \ MB[ZΛͬͨ΄͏͕͍͍͔ WBMVJ.BJO"DUJWJUZ6JCZMB[Z\ .BJO"DUJWJUZ6J ^ PWFSSJEFGVOPO$SFBUF TBWFE*OTUBODF4UBUF#VOEMF QFSTJTUFOU4UBUF1FSTJTUBCMF#VOEMF
\ TVQFSPO$SFBUF TBWFE*OTUBODF4UBUF QFSTJTUFOU4UBUF VJTFU$POUFOU7JFX UIJT VJUFYU7JFX UFYUl"1*͔Βͱ͖ͬͯͨͱ͔z ^ ^ DMBTT.Z"DUJWJUZ6*"OLP$PNQPOFOU.Z"DUJWJUZ\ WBSUFYU7JFX5FYU7JFX OVMM PWFSSJEFGVODSFBUF7JFX VJ"OLP$POUFYU.Z"DUJWJUZ XJUI VJ \ লུ ^ ^ ΫϥεΛ͚ͨྫ
DMBTT.Z"DUJWJUZ"QQ$PNQBU"DUJWJUZ \ MB[ZΛͬͨ΄͏͕͍͍͔ WBMVJ.BJO"DUJWJUZ6JCZMB[Z\ .BJO"DUJWJUZ6J ^ PWFSSJEFGVOPO$SFBUF TBWFE*OTUBODF4UBUF#VOEMF QFSTJTUFOU4UBUF1FSTJTUBCMF#VOEMF
\ TVQFSPO$SFBUF TBWFE*OTUBODF4UBUF QFSTJTUFOU4UBUF VJTFU$POUFOU7JFX UIJT VJUFYU7JFX UFYUl"1*͔Βͱ͖ͬͯͨͱ͔z ^ ^ DMBTT.Z"DUJWJUZ6*"OLP$PNQPOFOU.Z"DUJWJUZ\ WBSUFYU7JFX5FYU7JFX OVMMຊ͜͜ͰOVMMΛೖΕͨ͘ͳ͍ʜʜԿ͔͍͍ํ๏ PWFSSJEFGVODSFBUF7JFX VJ"OLP$POUFYU.Z"DUJWJUZ XJUI VJ \ লུ ^ ^ ΫϥεΛ͚ͨྫ
class ViewBinder<M>(val function: (M) -> Unit) : ReadWriteProperty<Any, M> {
private var mValue: M? = null override fun getValue(thisRef: Any, property: KProperty<*>): M = mValue as M override fun setValue(thisRef: Any, property: KProperty<*>, value: M) { mValue = value function(value) } } /////////////////////////////////////// var user: User? by ViewBinder { // userのセッターが呼ばれた時にこの関数が呼ばれる // このときActivityがクローズされていたら? // activityUiThreadWithContextの中で呼ぶこと when (it) { null -> { } else -> { ui.textView?.apply { text = it?.name } } } } 7JFX#JOEFS