這篇就來用上次學到的Canvas,來做這個範例動畫。
需求很簡單,點下+按鈕會展開3個Icon讓使用者選擇。
我們先來分析一下怎麼做。
UI分為2個部分
事件:點下+按鈕時
事件:點下x按鈕時
這個範例,我們把他做成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"
}
})
繪圖及設定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