Android 自定义下拉菜单的实现(基于PopupWindow+RecyclerView)

您所在的位置:网站首页 安卓下拉控件怎么打开设置 Android 自定义下拉菜单的实现(基于PopupWindow+RecyclerView)

Android 自定义下拉菜单的实现(基于PopupWindow+RecyclerView)

2023-09-13 11:49| 来源: 网络整理| 查看: 265

文章目录 一、引言二、效果三、代码实现四、结语

一、引言

安卓自带的Spinner局限性较大,基本不能满足开发样式要求,当前又没有成熟的相关框架,所以决定自己使用PopupWindow实现一个下拉菜单

二、效果

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

三、代码实现

布局: 新建xml文件:layout_dropdown_menu

在需要使用的地方引用

为下面布局添加一个遮罩的View: ps:比如我下拉框下面是一个rv,使用FrameLayout布局,为rv添加一个相同大小的View,来实现遮罩效果(当然有更好的实现方式欢迎私信我)

最后添加动画文件: style.xm

@anim/pop_enter_anim @anim/pop_exit_anim

pop_enter_anim.xml

pop_exit_anim.xml

代码: 新建一个DropdownMenu类,进行基本封装

package cn.edu.swu.reptile_android.ui.base import android.content.Context import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.animation.AnimationUtils import android.widget.ImageView import android.widget.LinearLayout import android.widget.PopupWindow import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import cn.edu.swu.reptile_android.R class DropdownMenu ( val context: Context? ) { lateinit var maskView: View lateinit var tabView: LinearLayout lateinit var tabTitle: TextView lateinit var tabIcon: ImageView lateinit var data: List private var onItemSelectListener: OnItemSelectListener? = null public fun init(view: View,data: List) { this.data = data tabView = view.findViewById(R.id.ly_dropdown_tab) tabTitle = view.findViewById(R.id.tv_dropdown_title) tabIcon = view.findViewById(R.id.iv_dropdown_icon) maskView = view.findViewById(R.id.mask_view) //默认显示item tabTitle.text = data[0] tabView.setOnClickListener { //角标变化 tabIcon.setImageResource(R.drawable.ic_down) //遮罩层动画 maskView.startAnimation( AnimationUtils.loadAnimation( context, R.anim.view_mask_enter_anim ) ) //弹出popWin showPopupWindow(tabView) } } public fun setOnItemSelectListener(onItemSelectListener: OnItemSelectListener){ this.onItemSelectListener = onItemSelectListener } interface OnItemSelectListener{ fun onItemSelect(position: Int) fun onDismiss() } private fun showPopupWindow(tabView: View) { val contentView: View = LayoutInflater.from(context).inflate(R.layout.popup_dropdown_menu, null) val popWindow = PopupWindow( contentView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true ) popWindow.contentView = contentView //RV val dropdownRv: RecyclerView = contentView.findViewById(R.id.rv) dropdownRv.layoutManager = LinearLayoutManager(contentView.context) val adapter = BaseAdapter(R.layout.item_rv_dropdown, data) { view, s -> view.findViewById(R.id.tv_item_title).text = s if (s == tabTitle.text) { //当前选中的item view.findViewById(R.id.tv_item_title).setTextColor(Color.BLACK) view.findViewById(R.id.iv_item_icon).visibility = View.VISIBLE } } //select item adapter.setOnItemClickListener(object : BaseAdapter.OnItemClickListener { override fun onItemClick(position: Int) { popWindow.dismiss() tabTitle.text = data[position] //加载数据 //暴露给调用者自定义选项逻辑 onItemSelectListener?.onItemSelect(position) } }) dropdownRv.adapter = adapter //弹出动画 popWindow.animationStyle = R.style.popwin_anim //遮罩效果 maskView.visibility = View.VISIBLE popWindow.setOnDismissListener { maskView.visibility = View.GONE tabIcon.setImageResource(R.drawable.ic_up) onItemSelectListener?.onDismiss() } //弹出窗口 popWindow.showAsDropDown(tabView) } }

最后,在Activity或者Fragment中使用:

private fun initDropdownMenu(view: View) { val dropdownMenu = DropdownMenu(context) dropdownMenu.init(view, vm.dropdownData) dropdownMenu.setOnItemSelectListener(object : DropdownMenu.OnItemSelectListener { override fun onItemSelect(position: Int) { //点击item后逻辑(加载数据?) } override fun onDismiss() { } }) } 四、结语

自己实现的一个基于PopupWindow和RecyclerView实现的下拉菜单,几乎自己实现,可能想法不太成熟,比如遮罩的实现和对于控件的一些封装还存在一些问题,这里仅提供一些思路,有更好的想法欢迎私信讨论。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3