iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Software Development

Android 鐵人賽: 天命最高 - 陪伴大家一步步打造屬於自己的app系列 第 21

Android 選單大集合:Menu、Dialog、WebView 到 Navigation,一次搞懂 App 的操作入口

  • 分享至 

  • xImage
  •  

我會以你這次最新上傳的程式重新定位 Day 21。這批內容已經不是前一版的 BMI,而是完整進入 Android 的 Menu、Dialog、Spinner、NumberPicker、WebView、Navigation Drawer、Date/Time Picker、Bottom Navigation;另外你新加入的三張貓咪圖片也實際用在 Menu 3 與 Bottom Navigation 的選項中。

Day 21|Android 選單大集合:Menu、Dialog、WebView 到 Navigation,一次搞懂 App 的操作入口

前面幾天,我們已經從 ActivityIntent 慢慢做到可以互動的 Android App。

今天要進入另一個每天使用 App 都一定會遇到的東西:

Menu 選單與 Navigation 導航

手機畫面不可能把所有功能都塞成 Button。

例如:

⋮ 更多功能
☰ 側邊選單
🏠 首頁
🐱 Cat
🐶 Dog
📅 日期
🕐 時間
🌐 Web

這些其實都是 App 的「操作入口」。

今天的練習量相當大,從最基本的 Options Menu 開始,一路做到:

Options Menu
     ↓
SubMenu
     ↓
AlertDialog
     ↓
Intent / Activity
     ↓
Spinner / NumberPicker
     ↓
Custom Dialog
     ↓
WebView
     ↓
Navigation Drawer
     ↓
DatePicker / TimePicker
     ↓
Bottom Navigation

可以說今天是在練習:

Android App 到底要怎麼讓使用者「找到功能、選擇功能、切換功能」。


🗺️ Day 21 完整學習地圖

                    Android Menu / Navigation
                              │
          ┌───────────────────┼───────────────────┐
          ↓                   ↓                   ↓
     Options Menu         Selection UI       Navigation UI
          │                   │                   │
    ┌─────┴─────┐       ┌─────┴─────┐      ┌─────┴──────┐
    ↓           ↓       ↓           ↓      ↓            ↓
 SubMenu    AlertDialog Spinner NumberPicker Drawer  Bottom Nav
    │           │                           │            │
    ↓           ↓                           ↓            ↓
 Image      Intent                      ☰ Menu        🐱🐶 Menu
 Change        │
               ↓
          DisplayActivity

                Custom Dialog
                     │
                     ↓
                  Intent
                     │
                     ↓
                 WebView

             DatePicker
                 │
                 ↓
           TimeActivity
                 │
                 ↓
             TimePicker

今天不是單純做一個元件,而是一次把 Android 常見的互動方式串起來。


Part 1:Options Menu — 從最基本的選單開始

第一個範例沒有使用 XML Menu,而是直接利用 Kotlin 建立選單。

首先定義每一個 Menu ID:

companion object {

    const val ChangPicture = Menu.FIRST
    const val ChangeColor = Menu.FIRST + 1
    const val ChangeText = Menu.FIRST + 2

    const val Text1 = Menu.FIRST + 3
    const val Text2 = Menu.FIRST + 4

    const val About = Menu.FIRST + 5
}

接著覆寫:

override fun onCreateOptionsMenu(menu: Menu?): Boolean {

    super.onCreateOptionsMenu(menu)

    menu?.add(
        1,
        ChangPicture,
        Menu.NONE,
        "Change picture"
    )

    menu?.add(
        1,
        ChangeColor,
        Menu.NONE,
        "Change color"
    )

    val subMenu = menu?.addSubMenu(
        1,
        ChangeText,
        Menu.NONE,
        "Change text"
    )

    subMenu?.add(
        1,
        Text1,
        Menu.NONE,
        "Text 1"
    )

    subMenu?.add(
        1,
        Text2,
        Menu.NONE,
        "Text 2"
    )

    menu?.add(
        1,
        About,
        Menu.NONE,
        "About"
    )

    return true
}

最後會形成:

⋮
├── Change picture
├── Change color
├── Change text  >
│      ├── Text 1
│      └── Text 2
└── About

📸 【圖 1:Options Menu 與 SubMenu 展開畫面】

這裡最重要的是:

onCreateOptionsMenu()

負責「建立 Menu」。

而:

onOptionsItemSelected()

負責「使用者點下 Menu 後要做什麼」。


Part 2:點 Menu 動態換圖片

Menu 建好之後,我們可以讓它真正控制畫面。

程式使用:

private var picFlag = true

記錄現在是哪一張圖片。

接著:

ChangPicture -> {

    Toast.makeText(
        this,
        "Change picture clicked",
        Toast.LENGTH_SHORT
    ).show()

    if (picFlag) {

        imgView.setImageResource(
            R.drawable.flower2
        )

        picFlag = false

    } else {

        imgView.setImageResource(
            R.drawable.flower1
        )

        picFlag = true
    }
}

流程就是:

Change picture
       ↓
   picFlag ?
    ↙     ↘
 true    false
  ↓        ↓
flower2  flower1
  ↓        ↓
false     true

同一個 Menu 就能讓兩張圖片來回切換。


Part 3:Menu 控制文字顏色

另一個 Menu:

Change color

程式:

ChangeColor -> {

    if (colorFlag) {

        textViewData.setTextColor(
            0x7FFF88FF.toInt()
        )

        colorFlag = false

    } else {

        textViewData.setTextColor(
            0x7F2196F3.toInt()
        )

        colorFlag = true
    }
}

這跟換圖片的概念非常像:

Boolean Flag
     ↓
目前狀態
     ↓
切換狀態
     ↓
更新 UI

這種 Flag 的概念在 Android 開發非常常見。


Part 4:SubMenu 子選單

今天也第一次加入:

Change text
    ├── Text 1
    └── Text 2

程式:

Text1 -> {

    textViewData.text =
        "There are lots of flowers"
}

Text2 -> {

    textViewData.text =
        "This is a pretty flower"
}

因此:

Menu
 ↓
Change text
 ↓
SubMenu
 ├── Text 1
 └── Text 2

比全部塞在第一層 Menu 更容易整理。


Part 5:About 不只是文字,而是 AlertDialog

點選:

About

不是單純 Toast,而是開啟:

AlertDialog.Builder

完整邏輯:

val builder =
    AlertDialog.Builder(this@MainActivity)

builder.setTitle(
    "About option menu"
)

builder.setIcon(
    android.R.drawable.ic_dialog_info
)

builder.setMessage(
    "This is alert dialog"
)

builder.setPositiveButton(
    "ok"
) { dialog, which ->

    textViewData.text =
        "About dialog"
}

builder.setNegativeButton(
    "cancel"
) { dialog, which ->

    textViewData.text =
        "Cancel dialog"

    dialog?.dismiss()
}

builder.show()

畫面概念:

┌───────────────────────────┐
│  ⓘ About option menu      │
│                           │
│  This is alert dialog     │
│                           │
│       CANCEL       OK     │
└───────────────────────────┘

📸 【圖 2:About AlertDialog】

這就開始出現真正 App 常見的操作方式了。


Part 6:Menu XML — 把選單從 Kotlin 分離出去

第二版 Menu 不再全部使用:

menu.add()

而改成:

override fun onCreateOptionsMenu(
    menu: Menu
): Boolean {

    super.onCreateOptionsMenu(menu)

    menuInflater.inflate(
        R.menu.setup,
        menu
    )

    return true
}

也就是:

res/
└── menu/
     └── setup.xml

負責定義 Menu。

而:

MainActivity.kt

只負責處理點擊行為。

架構變成:

setup.xml
   │
   ↓
Menu UI
   │
   ↓
onOptionsItemSelected()
   │
   ↓
Kotlin Logic

這種做法也讓 UI 與程式邏輯分工得更清楚。


Part 7:AlertDialog + Intent → DisplayActivity

Menu 2 又再進一步。

點擊:

About

首先:

val builder =
    AlertDialog.Builder(this@MainActivity)

顯示:

Menu App

Would you like to change
to Display Activity?

              OK

按下 OK:

builder.setPositiveButton("OK") {
    dialog, _ ->

    val intent = Intent(
        this@MainActivity,
        DisplayActivity::class.java
    )

    startActivity(intent)

    dialog.dismiss()
}

因此流程變成:

MainActivity
     ↓
Options Menu
     ↓
About
     ↓
AlertDialog
     ↓
    OK
     ↓
   Intent
     ↓
DisplayActivity

這裡就把昨天學到的 Intent 和今天的 Menu 串起來了。


Part 8:DisplayActivity 加上返回箭頭

進入 DisplayActivity 後:

supportActionBar?.title =
    "Display Page"

接著:

supportActionBar
    ?.setDisplayHomeAsUpEnabled(true)

這會讓 ActionBar 左邊出現:

← Display Page

再處理:

override fun onOptionsItemSelected(
    item: MenuItem
): Boolean {

    if (
        item.itemId ==
        android.R.id.home
    ) {

        finish()
    }

    return super.onOptionsItemSelected(item)
}

流程:

MainActivity
     │
     ↓
DisplayActivity
     │
     ↓
 ← 返回
     │
     ↓
 finish()
     │
     ↓
MainActivity

📸 【圖 3:DisplayActivity 左上角返回箭頭】


Part 9:🐱 今天的新主角 — Cat Menu

這次最新資料裡加入了:

Flower
Cat 1
Cat 2
Cat 3
Dog 1
Dog 2
Dog 3

使用者選擇不同 Menu,ImageView 就會立即換圖片。

例如:

R.id.menu_cat1 -> {

    textViewData.text =
        "It is Cat 1"

    imageViewPic.setImageResource(
        R.drawable.cat_1
    )
}

Cat 2:

R.id.menu_cat2 -> {

    textViewData.text =
        "It is Cat 2"

    imageViewPic.setImageResource(
        R.drawable.cat_2
    )
}

Cat 3:

R.id.menu_cat3 -> {

    textViewData.text =
        "It is Cat 3"

    imageViewPic.setImageResource(
        R.drawable.cat_3
    )
}

🐱 Cat 1

【直接放今天上傳的 cat_1.jpg】

這張就是:

R.drawable.cat_1

點:

Cat 1

畫面:

┌────────────────────┐
│     It is Cat 1    │
│                    │
│      [ CAT 1 ]     │
│                    │
└────────────────────┘

🐱 Cat 2

【直接放今天上傳的 cat_2.jpg】

對應:

R.drawable.cat_2

選擇:

Cat 2

執行:

textViewData.text =
    "It is Cat 2"

imageViewPic.setImageResource(
    R.drawable.cat_2
)

🐱 Cat 3

【直接放今天上傳的 cat_3.jpg】

對應:

R.drawable.cat_3

所以整個 Menu 3 可以理解為:

             Menu
              │
     ┌────────┼────────┐
     ↓        ↓        ↓
   Cat 1    Cat 2    Cat 3
     │        │        │
     ↓        ↓        ↓
 cat_1.jpg cat_2.jpg cat_3.jpg
     │        │        │
     └────────┼────────┘
              ↓
          ImageView

📸 【圖 4:Cat 1 / Cat 2 / Cat 3 三張圖片並排】

這個範例非常適合放在文章首圖附近,因為可以直接看出:

Menu 選了什麼,畫面就跟著變。


Part 10:Spinner — 下拉式選單

接下來是另外一種 Selection 元件:

Spinner

程式先取得:

spinner1 =
    findViewById(R.id.spinner_1)

spinner2 =
    findViewById(R.id.spinner_2)

資料來源:

val countryArray =
    resources.getStringArray(
        R.array.country
    )

再建立:

val adapter =
    ArrayAdapter.createFromResource(
        this@MainActivity,
        R.array.country,
        R.layout.simple_spinner_item
    )

設定展開畫面:

adapter.setDropDownViewResource(
    R.layout.simple_spinner_dropdown_item
)

最後:

spinner1.adapter = adapter
spinner2.adapter = adapter

結構:

String Array
     ↓
ArrayAdapter
     ↓
Spinner
     ↓
使用者選擇
     ↓
onItemSelected()
     ↓
TextView

Part 11:NumberPicker 不一定只能選數字

這個範例也很有意思。

第一個:

numberPicker1.minValue = 0
numberPicker1.maxValue = 100
numberPicker1.value = 5

就是:

4
[5]
6

但第二個 NumberPicker:

numberPicker2.minValue = 0

numberPicker2.maxValue =
    countryArray.size - 1

numberPicker2.displayedValues =
    countryArray

竟然可以顯示國家名稱。

也就是:

Taiwan
Japan
USA
Korea
...

當使用者改變:

numberPicker2
    .setOnValueChangedListener {
        picker,
        oldVal,
        newVal ->

        textViewResult.text =
            "picker 2 = " +
            countryArray[newVal]
    }

📸 【圖 5:Spinner + NumberPicker 選擇國家】


Part 12:Custom Dialog — 自己設計登入視窗

接著進入更實用的範例。

點:

LOGIN

不是直接換 Activity,而是:

val myBuilder =
    Dialog(this@MainActivity)

myBuilder.setContentView(
    R.layout.dialog_layout
)

也就是自己建立:

dialog_layout.xml

內容包含:

┌─────────────────────────┐
│ Name                    │
│ [____________________]  │
│                         │
│ Email                   │
│ [____________________]  │
│                         │
│   CANCEL        OK      │
└─────────────────────────┘

取得 Dialog 裡面的 View:

val editTextName =
    myBuilder.findViewById<EditText>(
        R.id.editText_dialogName
    )

val editTextEmail =
    myBuilder.findViewById<EditText>(
        R.id.editText_dialogEmail
    )

按 OK:

val name =
    editTextName.text.toString()

val email =
    editTextEmail.text.toString()

然後:

Toast.makeText(
    this@MainActivity,
    "name = $name , email = $email",
    Toast.LENGTH_SHORT
).show()

Part 13:Dialog → Intent → WebView

按下 OK 後:

val intent =
    Intent(
        this@MainActivity,
        WebActivity::class.java
    )

startActivity(intent)

流程:

MainActivity
     ↓
   LOGIN
     ↓
Custom Dialog
     ↓
Name + Email
     ↓
     OK
     ↓
   Intent
     ↓
 WebActivity
     ↓
   WebView

這就開始很像真正的登入流程。


Part 14:WebView — 在自己的 App 裡開網頁

WebActivity 裡使用:

private lateinit var webView: WebView

初始化:

webView =
    findViewById(
        R.id.webView_id
    )

接著:

webView.settings.apply {

    javaScriptEnabled = true

    setSupportZoom(true)

    builtInZoomControls = true
}

開啟 JavaScript:

javaScriptEnabled = true

支援縮放:

setSupportZoom(true)
builtInZoomControls = true

Part 15:網址空白就開 Yahoo

按下 Link:

buttonLink.setOnClickListener {

    if (editTextIpAddr.length() == 0) {

        ipAddr =
            "https://tw.yahoo.com/"

    } else {

        ipAddr =
            editTextIpAddr.text.toString()
    }

    webView.webViewClient =
        WebViewClient()

    webView.loadUrl(ipAddr)
}

所以:

網址欄位
   │
   ├── 空白
   │    ↓
   │ Yahoo Taiwan
   │
   └── 有網址
        ↓
     使用輸入網址
        ↓
   WebView.loadUrl()

📸 【圖 6:WebView 載入網站畫面】


Part 16:Navigation Drawer — ☰ 側邊選單

再來是現在很多 App 都會看到的:

也就是 Navigation Drawer。

主要使用:

DrawerLayout

以及:

NavigationView

初始化:

myDrawer =
    findViewById(
        R.id.drawerlayout_id
    )

navView =
    findViewById(
        R.id.navigationView
    )

再建立:

drawerToggle =
    ActionBarDrawerToggle(
        this,
        myDrawer,
        R.string.open,
        R.string.close
    )

設定:

myDrawer.addDrawerListener(
    drawerToggle
)

drawerToggle.syncState()

於是 ActionBar 左邊就會出現:


Part 17:NavigationView 點擊事件

選 Item:

navView
    .setNavigationItemSelectedListener {
        item ->

        when (item.itemId) {

            R.id.nav_item1 -> {
                textViewData.text =
                    "Item 1"
            }

            R.id.nav_item2 -> {
                textViewData.text =
                    "Item 2"
            }

            R.id.nav_item3 -> {
                textViewData.text =
                    "Item 3"
            }
        }

        myDrawer.closeDrawers()

        true
    }

注意最後:

myDrawer.closeDrawers()

使用者選完之後把 Drawer 收回。

流程:

☰
↓
Drawer 開啟
↓
Item 1
Item 2
Item 3
↓
選擇
↓
更新 TextView
↓
closeDrawers()

📸 【圖 7:Navigation Drawer 展開畫面】


Part 18:DatePicker — 日期選擇

接著做到日期。

首先:

now =
    Calendar.getInstance()

取得:

val year =
    now.get(Calendar.YEAR)

val month =
    now.get(Calendar.MONTH)

val day =
    now.get(Calendar.DAY_OF_MONTH)

初始化:

datePicker.init(
    year,
    month,
    day
) { _, year, monthOfYear, dayOfMonth ->

    textViewData.text =
        "$selectPrefix$year/" +
        "${monthOfYear + 1}/" +
        "$dayOfMonth"
}

注意:

monthOfYear + 1

因為 Calendar.MONTH 是從:

0

開始計算。


Part 19:DatePickerDialog

Menu 選:

Date

執行:

val dateDialog =
    DatePickerDialog(
        this@MainActivity,
        myDate,
        now.get(Calendar.YEAR),
        now.get(Calendar.MONTH),
        now.get(Calendar.DAY_OF_MONTH)
    )

dateDialog.setMessage(
    "Please select date"
)

dateDialog.show()

📸 【圖 8:DatePickerDialog 日期選擇畫面】

選完後:

override fun onDateSet(
    view: DatePicker?,
    year: Int,
    month: Int,
    dayOfMonth: Int
) {

    now.set(
        Calendar.YEAR,
        year
    )

    now.set(
        Calendar.MONTH,
        month
    )

    now.set(
        Calendar.DAY_OF_MONTH,
        dayOfMonth
    )

    textViewData.text =
        "$selectPrefix$year/" +
        "${month + 1}/" +
        "$dayOfMonth"

    datePicker.updateDate(
        year,
        month,
        dayOfMonth
    )
}

Part 20:Date Menu → TimeActivity

另一個 Menu:

Time

直接:

val intent =
    Intent(
        this@MainActivity,
        TimeActivity::class.java
    )

startActivity(intent)

所以:

Date Activity
      ↓
    Menu
      ↓
    Time
      ↓
    Intent
      ↓
TimeActivity

Part 21:TimePickerDialog

TimeActivity 取得現在時間:

now =
    Calendar.getInstance()

val hour =
    now.get(
        Calendar.HOUR_OF_DAY
    )

val minute =
    now.get(
        Calendar.MINUTE
    )

設定:

timePicker.setIs24HourView(
    true
)

所以使用:

24 小時制

按下按鈕:

val timeDialog =
    TimePickerDialog(
        this@TimeActivity,
        MyTime(),
        hour,
        minute,
        true
    )

timeDialog.setMessage(
    "Select time"
)

timeDialog.show()

使用者選完:

override fun onTimeSet(
    view: TimePicker?,
    hourOfDay: Int,
    minute: Int
) {

    textViewData.text =
        "Selected time: " +
        "$hourOfDay:$minute"
}

📸 【圖 9:TimePickerDialog 時間選擇畫面】


Part 22:Bottom Navigation — App 底部選單

最後做到另一個非常常見的 UI:

┌────────────────────────────┐
│                            │
│         App Content        │
│                            │
├────────────────────────────┤
│ 🐱   🐱   +   🐱   🐶   ⋮ │
└────────────────────────────┘

使用:

BottomNavigationView

以及:

FloatingActionButton

取得:

val bottomNavigationView:
    BottomNavigationView =
        findViewById(
            R.id.bottomAppBar_id
        )

val floatingButton:
    FloatingActionButton =
        findViewById(
            R.id.floatingActionButton_id
        )

Part 23:🐱 Cat 1、Cat 2、Cat 3 放進 Bottom Navigation

這次你提供的三張貓咪圖片,在這個範例也可以作為 Bottom Navigation 的圖示資源。

程式特別設定:

bottomNavigationView
    .itemIconTintList = null

這一行很重要。

Android Material 元件預設可能會幫 Menu Icon 套上 Tint 顏色。

如果我們使用的是:

🐱 真實貓咪圖片

就不希望系統把整張圖片染成單色。

因此:

itemIconTintList = null

保留圖片原本的顏色。

另外:

bottomNavigationView
    .isItemActiveIndicatorEnabled =
        false

關閉預設 Active Indicator。


Part 24:Bottom Navigation 點擊事件

bottomNavigationView
    .setOnItemSelectedListener {
        item ->

        when (item.itemId) {

            R.id.menu_cat1 -> {

                textViewData1.text =
                    "Cat 1"
            }

            R.id.menu_cat2 -> {

                textViewData1.text =
                    "Cat 2"
            }

            R.id.menu_cat3 -> {

                textViewData1.text =
                    "Cat 3"
            }

            R.id.menu_dog1 -> {

                textViewData2.text =
                    "Dog 1"
            }

            R.id.menu_dog2 -> {

                textViewData2.text =
                    "Dog 2"
            }

            R.id.menu_about -> {

                textViewData2.text =
                    "About bottom menu"
            }
        }

        true
    }

因此:

🐱 Cat1 → "Cat 1"
🐱 Cat2 → "Cat 2"
🐱 Cat3 → "Cat 3"

🐶 Dog1 → "Dog 1"
🐶 Dog2 → "Dog 2"

ⓘ About → "About bottom menu"

📸 【圖 10:三隻貓咪作為 Bottom Navigation 圖示】


Part 25:FloatingActionButton

中間還有:

Floating Action Button。

事件:

floatingButton.setOnClickListener {

    Toast.makeText(
        this@MainActivity,
        "Floating button is pressed",
        Toast.LENGTH_SHORT
    ).show()
}

按下後:

Floating button is pressed

這就是 Android 常看到的:

       +
      FAB

🧠 今天最重要的觀念

今天看似做了很多不同元件,但其實核心概念只有一件事情:

「使用者要如何操作 App?」

可以整理成:

UI 適合用途
Options Menu 次要功能/設定
SubMenu 分類功能
AlertDialog 確認操作
Custom Dialog 自訂輸入
Spinner 下拉選擇
NumberPicker 數字/項目選擇
Navigation Drawer 大型功能分類
Bottom Navigation App 主要頁面
DatePicker 日期選擇
TimePicker 時間選擇
FloatingActionButton 主要快捷動作
WebView App 內顯示網頁

🐱 今天的 Cat Menu 流程圖

                  Android App
                       │
                       ↓
                 Options Menu
                       │
          ┌────────────┼────────────┐
          ↓            ↓            ↓
        Cat 1        Cat 2        Cat 3
          │            │            │
          ↓            ↓            ↓
      cat_1.jpg     cat_2.jpg     cat_3.jpg
          │            │            │
          └────────────┼────────────┘
                       ↓
                   ImageView
                       ↓
              畫面立即切換圖片

而另一組 Navigation:

                 Bottom Navigation
                        │
       ┌────────────────┼────────────────┐
       ↓                ↓                ↓
      🐱               🐶               ⓘ
     Cats             Dogs             About
       │
 ┌─────┼─────┐
 ↓     ↓     ↓
Cat1  Cat2  Cat3

這正好把今天最新加入的三張貓咪圖片實際帶進 Android Menu。


📌 Day 21 今日成果

從最簡單的:

menu.add()

一路做到:

Options Menu
      ↓
SubMenu
      ↓
AlertDialog
      ↓
Intent
      ↓
Activity

再延伸:

Spinner
NumberPicker
Custom Dialog
WebView

最後進入真正 App 常用的:

Navigation Drawer
Bottom Navigation
FloatingActionButton
DatePicker
TimePicker

今天最大的收穫就是開始了解:

Android App 不只有 Activity,還需要一套好的 Navigation,才能讓使用者知道「我在哪裡、功能在哪裡、下一步要去哪裡」。


💡 Day 21 心得

以前看到 Android App 左上角:

或右上角:

以及下面:

🏠   🔍   +   ❤️   👤

只會覺得「這就是 App 的按鈕」。

但實際寫過之後,才發現背後其實分成:

Menu
SubMenu
NavigationView
DrawerLayout
BottomNavigationView
FloatingActionButton

而且這些元件最後都離不開我們前面學過的 Kotlin:

when
if / else
Boolean
Listener
Intent
Activity
Array
Adapter

所以 Kotlin 基礎不是學完就丟掉,而是開始一點一點組成真正的 Android App。

今天甚至把三張貓咪圖片:

cat_1.jpg
cat_2.jpg
cat_3.jpg

放進 Menu 的切換邏輯中。

從:

點 Cat 1

到:

R.id.menu_cat1
        ↓
when
        ↓
setImageResource()
        ↓
cat_1
        ↓
ImageView 顯示貓咪

這個過程,就是 Android UI「事件驅動」最直接的例子。


🔜 下一步

完成今天的 Menu 與 Navigation 後,接下來就可以把:

Menu
  +
Activity
  +
Intent
  +
ListView / RecyclerView
  +
實際資料

組成更完整的多頁 Android App。

Day 21 完成!🐱🐱🐱

這版是依你最新這一批程式重新整理:Menu 1 有程式動態建立 Options Menu、SubMenu、換圖、換色與 AlertDialog;Menu 2 改用 XML Menu,並從 Dialog 透過 Intent 進入 DisplayActivity

另外,最新 Menu 3 確實有 cat_1cat_2cat_3 的選單切圖;後面的練習則一路涵蓋 Spinner/NumberPicker、Custom Dialog + WebView、Navigation Drawer、DatePicker/TimePicker 與 Bottom Navigation/FAB,所以我認為這次 Day 21 的主題用 **「Android 選單與 Navigation 大集合」**會比 BMI 更符合你今天真正的課程內容。


上一篇
Android Activity 資料傳遞實戰:從飲料點餐到會員註冊,掌握 Intent 雙向回傳
系列文
Android 鐵人賽: 天命最高 - 陪伴大家一步步打造屬於自己的app21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言