{"id":22780038,"url":"https://github.com/zyao89/zactionsheetview","last_synced_at":"2025-07-31T12:35:42.029Z","repository":{"id":144074594,"uuid":"92302061","full_name":"zyao89/ZActionSheetView","owner":"zyao89","description":"kotlin编写的自定义底部弹出选择框，主要用于学习Kotlin和分享的项目","archived":false,"fork":false,"pushed_at":"2017-05-24T14:43:42.000Z","size":167,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-05T15:52:40.316Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zyao89.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-24T14:33:18.000Z","updated_at":"2019-03-06T03:14:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"7d7e0f44-1f67-466a-9365-265f0559ca5b","html_url":"https://github.com/zyao89/ZActionSheetView","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyao89%2FZActionSheetView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyao89%2FZActionSheetView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyao89%2FZActionSheetView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyao89%2FZActionSheetView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zyao89","download_url":"https://codeload.github.com/zyao89/ZActionSheetView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246326783,"owners_count":20759439,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-11T20:12:07.031Z","updated_at":"2025-03-30T14:15:46.375Z","avatar_url":"https://github.com/zyao89.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ZActionSheetView\nkotlin编写的自定义底部弹出选择框，主要用于学习Kotlin和分享的项目\n\n---\n\n##Kotlin 引言\n\u003e**Google IO 2017 宣布了 Kotlin 会成为 Android 官方开发语言。**\n\nKotlin 是一个基于 JVM 的新的编程语言，由 [JetBrains](http://baike.baidu.com/item/JetBrains) 开发。\nKotlin可以编译成Java字节码，也可以编译成JavaScript，方便在没有JVM的设备上运行。\nJetBrains，作为目前广受欢迎的Java IDE [IntelliJ](http://baike.baidu.com/item/IntelliJ) 的提供商，在 Apache 许可下已经开源其Kotlin 编程语言。\nKotlin已正式成为Android官方开发语言。\n\n## 正文\n今天我主要介绍的是使用Kotlin去写一个简单的自定义View，从而学习Kotlin语言的各种魅力。\n\n### Gradle引入\nmodel中\n```gradle\napply plugin: 'kotlin-android'\n\nandroid {\n    sourceSets {\n        main.java.srcDirs += 'src/main/kotlin'\n    }\n}\n\ncompile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.2-4'\n```\n\n工程中引入\n```gradle\nbuildscript {\n    ext.kotlin_version = '1.1.2-4'\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:2.3.2'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n```\n\n### Kotlin代码\n常量：ActionSheetConstants.kt\n```kotlin\n/**\n * Created by zyao89 on 2017/5/24.\n * Contact me at 305161066@qq.com or zyao89@gmail.com\n * For more projects: https://github.com/zyao89\n * My Blog: http://zyao89.me\n */\nconst val DEFAULT_COLOR: Int = 0xFF_02_7B_FF.toInt()\nconst val DEFAULT_SHADE_COLOR: Int = 0x88_00_00_00.toInt()\nconst val DEFAULT_BTN_CANCEL_COLOR: Int = 0xFF_87_87_87.toInt()\nconst val DEFAULT_BTN_SELECT_COLOR: Int = 0xFF_3D_DD_B0.toInt()\n```\n\n代码块一： BaseActionSheetView.kt\n```kotlin\n/**\n * Created by zyao89 on 2017/5/24.\n * Contact me at 305161066@qq.com or zyao89@gmail.com\n * For more projects: https://github.com/zyao89\n * My Blog: http://zyao89.me\n */\nabstract class BaseActionSheetView(val context: Context, val list: List\u003cActionSheetBtnInfo\u003e, val rootView: ViewGroup = ((context as Activity).window.decorView as ViewGroup)) : View.OnClickListener, View.OnTouchListener {\n    protected val mBtnViewList: LinkedList\u003cTextView\u003e = LinkedList()\n    protected var mCustomContent: LinearLayout? = null\n    protected var mBtnCancel: TextView? = null\n    //POP总容器\n    private var mFrameLayout: FrameLayout = FrameLayout(context)\n            .apply {\n                setBackgroundColor(DEFAULT_SHADE_COLOR)\n            }\n    private var mPopupWindow: PopupWindow = PopupWindow(this.initView()\n            .apply {\n                mCustomContent = findViewById(R.id.pop_layout) as LinearLayout\n                setOnTouchListener(this@BaseActionSheetView)\n            }, MATCH_PARENT, MATCH_PARENT, true)\n            .apply {\n                animationStyle = R.style.popwin_anim_style\n                setOnDismissListener { this@BaseActionSheetView.dismiss() }\n                inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED\n                softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE\n            }\n\n    init {\n        this.initBtn()\n        this.initCancel()\n    }\n\n    protected abstract fun initView(): View\n    protected abstract fun initBtn()\n    protected abstract fun initCancel()\n\n    override fun onClick(v: View?) {\n        when (v) {\n            mBtnCancel -\u003e {\n\n            }\n            is TextView, is Button -\u003e v.tag.takeIf { it is Int }?.let {\n                val onClickListener = list[v.tag as Int].onClickListener\n                onClickListener?.onClick(v)\n            }\n            else -\u003e {\n\n            }\n        }\n        mPopupWindow.dismiss()\n    }\n\n    override fun onTouch(v: View?, event: MotionEvent?): Boolean {\n        val height: Int = mCustomContent?.top!!.toInt()\n        val y: Int = event?.y!!.toInt()\n        when (event.action) {\n            MotionEvent.ACTION_UP -\u003e {\n                y.takeIf { it \u003c height }.let {\n                    println(\"y: $y\")\n                    println(\"height: $height\")\n                    mPopupWindow.dismiss()\n                }\n            }\n        }\n        return true\n    }\n\n    private fun dismiss() {\n        rootView.removeView(mFrameLayout)\n    }\n\n    fun setCancelText(text: String) {\n        this.mBtnCancel?.text = text\n    }\n\n    fun setCancelTextColor(color: Int) {\n        this.mBtnCancel?.setTextColor(color)\n    }\n\n    fun setCancelTextSize(size: Float) {\n        this.mBtnCancel?.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)\n    }\n\n    fun hideCancel() {\n        this.mBtnCancel?.visibility = View.GONE\n    }\n\n    fun show() {\n        rootView.addView(mFrameLayout, MATCH_PARENT, MATCH_PARENT)\n        mPopupWindow.showAtLocation(mFrameLayout, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)\n    }\n\n    /**\n     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)\n     */\n    protected fun dip2px(context: Context, dpValue: Float): Int {\n        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.resources.displayMetrics).toInt()\n    }\n}\n```\n\n代码块二：ActionSheetBtnInfo.kt\n```kotlin\n/**\n * Created by zyao89 on 2017/5/24.\n * Contact me at 305161066@qq.com or zyao89@gmail.com\n * For more projects: https://github.com/zyao89\n * My Blog: http://zyao89.me\n */\ndata class ActionSheetBtnInfo(var text: String, var textColor: Int = DEFAULT_COLOR, var backgroundResource: Int = R.drawable.custom_view_select_pop_selector_btn) : Serializable {\n    companion object {\n        //这里可以填写单例\n    }\n\n    var onClickListener: View.OnClickListener? = null\n\n    /**\n     * 自定义get和set方法\n     */\n    var textSize: Float? = null\n        get() = field\n        set(value) {\n            field = value\n        }\n}\n```\n\n代码块三：ActionSheetView.kt\n```kotlin\n/**\n * Created by zyao89 on 2017/5/24.\n * Contact me at 305161066@qq.com or zyao89@gmail.com\n * For more projects: https://github.com/zyao89\n * My Blog: http://zyao89.me\n */\nclass ActionSheetView(context: Context, list: List\u003cActionSheetBtnInfo\u003e) : BaseActionSheetView(context, list) {\n\n    override fun initView(): View {\n        return View.inflate(context, R.layout.custom_view_select_pop, null)\n    }\n\n    override fun initBtn() {\n        for ((index, btnInfo) in list.withIndex()) {\n            TextView(context)\n                    .apply {\n                        tag = index\n                        text = btnInfo.text\n                        btnInfo.textSize?.let {\n                            setTextSize(TypedValue.COMPLEX_UNIT_SP, it)\n                        }\n                        height = dip2px(context, 44.0f)\n                        gravity = Gravity.CENTER\n                        layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, dip2px(context, 44.0f))\n                        setTextColor(btnInfo.textColor)\n                        setBackgroundResource(btnInfo.backgroundResource)\n                        setOnClickListener(this@ActionSheetView)\n                    }\n                    .also {\n                        val layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)\n                        layoutParams.topMargin = dip2px(context, 5.0f)\n                        mCustomContent?.addView(it, index, layoutParams)\n                    }\n                    .let {\n                        mBtnViewList.add(it)\n                    }\n        }\n    }\n\n    override fun initCancel() {\n        mBtnCancel = TextView(context)\n                .apply {\n                    text = \"Cancel\"\n                    height = dip2px(context, 44.0f)\n                    gravity = Gravity.CENTER\n                    layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, dip2px(context, 44.0f))\n                    setTextColor(if (list.isEmpty()) DEFAULT_BTN_SELECT_COLOR else list[0].textColor)\n                    setBackgroundResource(if (list.isEmpty()) R.drawable.custom_view_select_pop_selector_btn else list[0].backgroundResource)\n                    setOnClickListener(this@ActionSheetView)\n                }\n                .apply {\n                    val layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)\n                    layoutParams.topMargin = dip2px(context, 15.0f)\n                    layoutParams.bottomMargin = dip2px(context, 20.0f)\n                    mCustomContent?.let {\n                        mCustomContent?.addView(this@apply, it.childCount, layoutParams)\n                    }\n                }\n    }\n}\n```\n\n代码块四：ActionSheetListView.kt\n```kotlin\n/**\n * Created by zyao89 on 2017/5/24.\n * Contact me at 305161066@qq.com or zyao89@gmail.com\n * For more projects: https://github.com/zyao89\n * My Blog: http://zyao89.me\n */\nclass ActionSheetListView(context: Context, list: List\u003cActionSheetBtnInfo\u003e) : BaseActionSheetView(context, list) {\n\n    override fun initView(): View {\n        return View.inflate(context, R.layout.custom_view_select_list_pop, null)\n    }\n\n    override fun initBtn() {\n        for ((index, btnInfo) in list.withIndex()) {\n            TextView(context)\n                    .apply {\n                        tag = index\n                        text = btnInfo.text\n                        btnInfo.textSize?.let {\n                            setTextSize(TypedValue.COMPLEX_UNIT_SP, it)\n                        }\n                        height = dip2px(context, 44.0f)\n                        gravity = Gravity.CENTER\n                        layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, dip2px(context, 44.0f))\n                        setTextColor(btnInfo.textColor)\n                        setBackgroundResource(R.drawable.custom_view_select_list_pop_selector_btn)\n                        setOnClickListener(this@ActionSheetListView)\n                    }\n                    .also {\n                        val layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)\n                        layoutParams.topMargin = 1\n                        mCustomContent?.addView(it, index, layoutParams)\n                    }\n                    .let {\n                        mBtnViewList.add(it)\n                    }\n        }\n    }\n\n    override fun initCancel() {\n        mBtnCancel = TextView(context)\n                .apply {\n                    text = \"Cancel\"\n                    height = dip2px(context, 44.0f)\n                    gravity = Gravity.CENTER\n                    layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, dip2px(context, 44.0f))\n                    setTextColor(DEFAULT_BTN_CANCEL_COLOR)\n                    setBackgroundResource(R.drawable.custom_view_select_list_pop_selector_btn)\n                    setOnClickListener(this@ActionSheetListView)\n                }\n                .apply {\n                    val layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)\n                    layoutParams.topMargin = 1\n                    layoutParams.bottomMargin = dip2px(context, 1.0f)\n                    mCustomContent?.let {\n                        mCustomContent?.addView(this@apply, it.childCount, layoutParams)\n                    }\n                }\n    }\n}\n```\n\n---\n### 布局文件Layout\nlayout布局一：custom_view_select_pop.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cRelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"wrap_content\"\n                android:gravity=\"center_horizontal\"\n                android:orientation=\"vertical\" \u003e\n\n    \u003cLinearLayout\n        android:id=\"@+id/pop_layout\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:layout_marginLeft=\"20dp\"\n        android:layout_marginRight=\"20dp\"\n        android:orientation=\"vertical\" \u003e\n    \u003c/LinearLayout\u003e\n\n\u003c/RelativeLayout\u003e\n\n```\n\n\nlayout布局二：custom_view_select_list_pop.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cRelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"wrap_content\"\n                android:gravity=\"center_horizontal\"\n                android:orientation=\"vertical\" \u003e\n\n    \u003cLinearLayout\n        android:id=\"@+id/pop_layout\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:orientation=\"vertical\" \u003e\n    \u003c/LinearLayout\u003e\n\n\u003c/RelativeLayout\u003e\n\n```\n\nanim文件\nppwindow_show_anim.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cset xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003ctranslate\n        android:duration=\"300\"\n        android:fromXDelta=\"0\"\n        android:toXDelta=\"0\"\n        android:fromYDelta=\"200\"\n        android:toYDelta=\"0\"\n        /\u003e\n    \u003calpha\n        android:duration=\"300\"\n        android:fromAlpha=\"0\"\n        android:toAlpha=\"1\"\n        /\u003e\n\u003c/set\u003e\n```\n\nppwindow_hide_anim.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cset xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003ctranslate\n        android:duration=\"200\"\n        android:fromXDelta=\"0\"\n        android:toXDelta=\"0\"\n        android:fromYDelta=\"0\"\n        android:toYDelta=\"200\"\n        /\u003e\n    \u003calpha\n        android:duration=\"200\"\n        android:fromAlpha=\"1\"\n        android:toAlpha=\"0\"\n        /\u003e\n\u003c/set\u003e\n```\n\ndrawable文件\ncustom_view_select_list_pop_selector_btn.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cselector xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003citem android:state_pressed=\"true\" \u003e\n        \u003cshape\u003e\n            \u003csolid android:color=\"#cccccccc\"/\u003e\n        \u003c/shape\u003e\n    \u003c/item\u003e\n    \u003citem\u003e\n        \u003cshape\u003e\n            \u003csolid android:color=\"@android:color/white\"/\u003e\n        \u003c/shape\u003e\n    \u003c/item\u003e\n\u003c/selector\u003e\n```\n\n\ncustom_view_select_pop_selector_btn.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cselector xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003citem android:state_pressed=\"true\" \u003e\n        \u003cshape\u003e\n            \u003csolid android:color=\"#cccccccc\"/\u003e\n            \u003ccorners android:radius=\"10dp\" /\u003e\n        \u003c/shape\u003e\n    \u003c/item\u003e\n    \u003citem  \u003e\n        \u003cshape\u003e\n            \u003csolid android:color=\"@android:color/white\"/\u003e\n            \u003ccorners android:radius=\"10dp\"/\u003e\n        \u003c/shape\u003e\n    \u003c/item\u003e\n\u003c/selector\u003e\n```\n\nstyles.xml\n```xml\n\u003cresources\u003e\n    \u003cstyle name=\"popwin_anim_style\"\u003e\n        \u003citem name=\"android:windowEnterAnimation\"\u003e@anim/ppwindow_show_anim\u003c/item\u003e\n        \u003citem name=\"android:windowExitAnimation\"\u003e@anim/ppwindow_hide_anim\u003c/item\u003e\n    \u003c/style\u003e\n\u003c/resources\u003e\n```\n\n### 演示\n\n![ActionSheetListView.png](capture/device-2017-05-24-224130.png)\n\n\n![ActionSheetView.png](capture/device-2017-05-24-224151.png)\n\n\nGitHub源码：[zyao89/ZActionSheetView](https://github.com/zyao89/ZActionSheetView)\n\n---\n\n\n`作者：Zyao89；转载请保留此行，谢谢；`\n\n个人博客：[http://zyao89.me](http://zyao89.me)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyao89%2Fzactionsheetview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzyao89%2Fzactionsheetview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyao89%2Fzactionsheetview/lists"}