最近学习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(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 语言最后方式就是在边写边学中学习