iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
2
Software Development

Android animation 30天上手系列 第 10

Day10 動畫範例:CustomSelector

這篇就來用上次學到的Canvas,來做這個範例動畫。

CustomSelector

需求很簡單,點下+按鈕會展開3個Icon讓使用者選擇。

我們先來分析一下怎麼做。
UI分為2個部分

  • 上方的Dialog
  • 下方的+

事件:點下+按鈕時

  • +按鈕要變為x按鈕
  • 由小至大顯示Dialog

事件:點下x按鈕時

  • x按鈕要變為+按鈕
  • 由大至小關閉Dialog

這個範例,我們把他做成CustomView,讓使用這個CustomSelector的人可以自行決定要傳入多少dialog上的icon

完成後的使用方式:
activity_main.xml,加入CustomSelector

<evan.chen.tutorial.customselector.CustomSelector
    android:id="@+id/select_dialog"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true" />

MainMactivity,使用setSelectIcon設定展開的圖示,使用IConSelectListener接收事件。

//放大icon array
val drawables = intArrayOf(R.mipmap.icon1, R.mipmap.icon2, R.mipmap.icon3)

selectDialog.setSelectIcon(drawables)

//事件
selectDialog.setListener(object : CustomSelector.IconSelectListener {
    //開啟Dialog
    override fun onOpen() {
        selectResult.text = ""
    }

    //被選取事件
    override fun onSelected(iconIndex: Int) {
        selectResult.text = "Select  icon: $iconIndex"
    }

    //點X事件。
    override fun onCancel() {
        selectResult.text = "Cancel"
    }
})

CustomSelector 做法

繪圖及設定Button點擊事件

  • 繪圖:+的按鈕
  • 繪圖:Dialog
  • 設定Button被點擊的事件
private fun setting() {
    View.inflate(context, R.layout.custom_selector, this)

    //繪制+的按鈕
    drawButton()
    //繪制Dialog
    drawDialog()
    //控制是否顯示Dialog
    displayDialog(false)

    //點下Button的事件
    select_imageview.setOnClickListener {

        //旋轉+按鈕
        rotateSelectImageView()

        //顯示Dialog
        displayDialog(!isOpen)

        //Callback
        if (isOpen) {
            listener?.onCancel()
        } else {
            listener?.onOpen()
        }

        isOpen = !isOpen
    }
}

處理點下+按鈕的事件

1.+按鈕要變為x按鈕
要轉+變成x,只要將圖片旋轉-45度即可

private fun rotateSelectImageView() {
    //點選+後,旋轉變成x
    val fromDegree: Float
    val toDegree: Float

    if (isOpen) {
        //旋轉由-45度到0度。開啟狀態(x) -> 關閉狀態(+)
        fromDegree = -45.0f
        toDegree = 0.0f

    } else {
        //旋轉由0度到-45度。開啟狀態(x) -> 關閉狀態(+)
        fromDegree = 0.0f
        toDegree = -45.0f
    }

    val animRotate = RotateAnimation(fromDegree, toDegree,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f)

    animRotate.duration = 300
    animRotate.fillAfter = true

    select_imageview.startAnimation(animRotate)
}

2.由小至大顯示Dialog

private fun displayDialog(display: Boolean) {
    //開啟、關閉Dialog
    var fromScale = 0.0f
    var toScale = 1.0f

    if (display) {
        //由小變大展開
        fromScale = 0.0f
        toScale = 1.0f
        this.dialog_select_linearlayout.visibility = View.VISIBLE
        this.dialog_select_linearlayout.bringToFront()
    } else {
        //由大變小縮起
        fromScale = 1.0f
        toScale = 0.0f
        this.dialog_select_linearlayout.visibility = View.GONE
    }

    //Scale動畫,顯示時由小放大,關閉時由大放小
    val anim = ScaleAnimation(
            fromScale, toScale,
            fromScale, toScale,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 1f)

    anim.duration = 300
    this.dialog_select_linearlayout.startAnimation(anim)
}

還記得嗎?我們是CustomView,可以讓使用者決定放多少icon

fun setSelectIcon(drawables: IntArray) {
    this.drawables = drawables
    setting()
}
//開啟、選取、取消的Listener
interface IconSelectListener {
    fun onOpen()
    fun onSelected(iconIndex: Int)
    fun onCancel()
}

完整程式:
https://github.com/evanchen76/CustomSelector


上一篇
Day09 Canvas 繪圖
下一篇
Day11 Frame Animation
系列文
Android animation 30天上手30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言