使用Kotlin實現百思不得姐彈出選單
阿新 • • 發佈:2019-01-22
最近學習kotlin ,kotlin 確實是一門非常nice的語言,從它的書寫到它的語法,都有吸引人的地方,學習一門新的語言最好的方法就是運用這門語言了,為了學習kotlin ,仿寫百思不得 姐 ,今天將不得姐的彈出選單記錄一下,先看一下效果
好了 下面使用kotlin 完成一下
一、實現思路
就使用最簡單的思路,首先將它用普通佈局搭建出來,在加入動畫,就可以完成了,OK ,kotlin 基本上百分之九十和Java相似,很好理解的一門語言,在Android開發中呢,它是完全相容的,並且為適配程式設計師的過渡期,做了和Java的呼叫,也就是說,我們這些沒有很多時間來學習kotlin 的人來說,相容開發是最好的選擇,說多了,,,,嗯嗯,佈局搭建是和Java開發的時候一樣的,
二、實現過程
下面是佈局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:alpha="0.9"
android:gravity="center_horizontal" >
<LinearLayout
android:id="@+id/ll_close"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
android:gravity="center">
<TextView
android:layout_width ="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="8dp"
android:text="@string/send_cancel" />
</LinearLayout>
<LinearLayout
android:id="@+id/voice_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/ll_close"
android:layout_alignLeft="@+id/video_window"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_voice" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_voice"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/link_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/ll_close"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_link" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_link"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/music_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/ll_close"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:layout_marginLeft="40dp"
android:layout_toRightOf="@id/link_window"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_music_album" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_music"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/photo_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/voice_window"
android:layout_centerHorizontal="true"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_picture" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_pic"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/video_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/voice_window"
android:layout_centerHorizontal="true"
android:layout_toLeftOf="@+id/photo_window"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_video_uninstall" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_video"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/satin_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/voice_window"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@+id/photo_window"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/send_text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/send_satin"
android:textColor="#606060"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
OK ,佈局完了之後,我們在分析一下,上面UI中的中間的按鈕,出發事件之後,是彈出來了一個佈局,覆蓋整體UI的佈局,那他是什麼呢?PopupWindow ,對沒錯 就是PopupWindow ,那我們要怎麼寫呢?
看程式碼
/**
* Created by mr.kong on 2017/11/17.
*/
class WritePostsPopWindow : PopupWindow, View.OnClickListener {
private lateinit var rootView: View
private lateinit var contentView: RelativeLayout
private lateinit var mContext: Activity
constructor(mContext: Activity) : super() {
this.mContext = mContext
}
fun showMoreWindow(anchor: View) {
//獲取LayoutInflater 物件 在kotlin中優點之一,不用指定定義的變數的型別,執行程式碼
//的時候,程式碼會更具其值確定其型別
val inflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
rootView = inflater.inflate(R.layout.fragment_write_posts, null)
//獲取螢幕的寬高
val height = mContext.windowManager.defaultDisplay.height
val width = mContext.windowManager.defaultDisplay.width
//PopupWindow設定佈局
setContentView(rootView)
this.width = width
//高度使用減掉狀態列的高度
this.height = (height - ScreenUtils.getStatusHeight(mContext)).toInt()
//找到我們的根佈局節點
contentView = rootView.findViewById(R.id.contentView)
//取消按鈕
val close = rootView.findViewById<LinearLayout>(R.id.ll_close)
close.setBackgroundColor(0xFFFFFFFF.toInt())
close.setOnClickListener(this)
showAnimation(contentView)
setBackgroundDrawable(mContext.resources.getDrawable(R.drawable.translucence_with_white))
isOutsideTouchable = true
isFocusable = true
showAtLocation(anchor, Gravity.BOTTOM, 0, 0)
}
private fun showAnimation(contentView: ViewGroup) {
//contentView 是我們剛才獲得的根節點 獲取在這個節點中的所有的 子節點的個數
var childCount: Int = contentView.childCount
KLogger.i("view", " " + childCount)
//kotlin 的迴圈的一種方法(有好幾種,每一種都有對應的優點和不足)
for (i in 0..childCount) {
val view = contentView.getChildAt(i)
if (view != null) {
if (view.id == R.id.ll_close) { //忽略取消控制元件
continue
}
//設定所有一級選單的點選事件
view.setOnClickListener(this)
view.visibility = View.INVISIBLE
//延遲顯示每個子檢視
//使用rxjava和rxAndroid 完成延遲操作 在不同時間中開始動畫 出現彈出時先後的效果
Observable.timer(i * 50.toLong(), TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
view.visibility = View.VISIBLE
/**
* ofFloat()
* arg1:view 物件
* arg2:動畫改變的型別
* arg3:args4: 依次是開始透明度和結束透明度
*/
val fadeAnim: ValueAnimator = ObjectAnimator.ofFloat(view, "translationY", 600F, 0F)
//設定動畫的時間
fadeAnim.duration = 300
fadeAnim.start()
}
}
}
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.video_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.link_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.voice_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.photo_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.satin_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.music_window -> {
Toast.makeText(mContext, "video_window", Toast.LENGTH_LONG).show()
}
R.id.ll_close -> {
if (isShowing) {
closeAnimation(contentView)
}
}
}
}
/**
* 關閉動畫
*/
private fun closeAnimation(contentView: RelativeLayout) {
for (i in 0..contentView.childCount) {
val view = contentView.getChildAt(i)
if (view != null) {
if (view.id == R.id.ll_close) { //忽略取消控制元件
continue
}
//設定所有一級選單的點選事件
view.setOnClickListener(this)
view.visibility = View.INVISIBLE
//延遲顯示每個子檢視
Observable.timer(((contentView.childCount - i - 1) * 30).toLong(), TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
view.visibility = View.VISIBLE
val fadeAnim: ValueAnimator = ObjectAnimator.ofFloat(view, "translationY", 0F, 600F)
fadeAnim.duration = 200
fadeAnim.run {
start()
addListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
//動畫迴圈播放的時候
}
override fun onAnimationEnd(animation: Animator?) {
//動畫結束的時候
view.visibility = View.INVISIBLE
}
override fun onAnimationCancel(animation: Animator?) {
//動畫被取消的時候
}
override fun onAnimationStart(animation: Animator?) {
//動畫開始的時候呼叫
}
})
}
}
//將個別的取出來 再延時顯示 製造效果
if (view.id == R.id.video_window) {
Observable.timer(((contentView.childCount - i) * 30 + 80).toLong(), TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
dismiss()
})
}
}
}
}
}
使用
R.id.main_writ_posts_btu -> {
val writePostsPopWindow = WritePostsPopWindow(this)
writePostsPopWindow.showMoreWindow(v)
}
上面程式碼中的註釋很詳細,至此 完成了不得姐的彈出選單的效果 ,其實kotlin 語言最後方式就是在邊寫邊學中學習