使用Kotlin实现百思不得姐弹出菜单

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

猜你喜欢

转载自blog.csdn.net/qq_32648731/article/details/78564266