Kotlin Fragment中长按触发透明背景PopupWindow或DialogFragment实现咨询
Android 长按触发用户操作弹窗实现方案
采用 DialogFragment 实现,自动支持点击外部关闭、半透明背景效果,适配横竖屏切换等场景,实现步骤如下:
1. 创建弹窗布局文件 res/layout/dialog_user_options.xml
你可以根据需求调整操作选项数量,布局参考代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="32dp" android:background="@drawable/bg_dialog_round" android:orientation="vertical" android:padding="16dp"> <!-- 顶部用户名区域 --> <TextView android:id="@+id/tv_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textStyle="bold" android:paddingVertical="12dp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#EEEEEE" android:layout_marginVertical="8dp"/> <!-- 操作选项,可自行增删 --> <TextView android:id="@+id/option_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="编辑用户" android:textSize="16sp" android:paddingVertical="12dp" android:drawablePadding="12dp" android:drawableStart="@drawable/ic_edit"/> <TextView android:id="@+id/option_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除用户" android:textSize="16sp" android:textColor="#F44336" android:paddingVertical="12dp" android:drawablePadding="12dp" android:drawableStart="@drawable/ic_delete"/> </LinearLayout>
需要自行创建圆角背景drawable bg_dialog_round.xml,设置圆角和白色背景即可。
2. 实现DialogFragment逻辑类
class UserOptionDialogFragment : DialogFragment() { // 回调接口处理操作点击 interface OnOptionClickListener { fun onEditUser(userId: Long) fun onDeleteUser(userId: Long) } private var listener: OnOptionClickListener? = null private lateinit var userId: Long private lateinit var userName: String companion object { // 标准参数传递方式 fun newInstance(userId: Long, userName: String): UserOptionDialogFragment { val fragment = UserOptionDialogFragment() val args = Bundle() args.putLong("USER_ID", userId) args.putString("USER_NAME", userName) fragment.arguments = args return fragment } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 读取传递的参数 arguments?.let { userId = it.getLong("USER_ID") userName = it.getString("USER_NAME", "") } // 绑定回调,父Fragment实现接口即可 listener = parentFragment as? OnOptionClickListener } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.dialog_user_options, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 填充用户名 view.findViewById<TextView>(R.id.tv_username).text = userName // 操作点击事件 view.findViewById<TextView>(R.id.option_edit).setOnClickListener { listener?.onEditUser(userId) dismiss() } view.findViewById<TextView>(R.id.option_delete).setOnClickListener { listener?.onDeleteUser(userId) dismiss() } } override fun onStart() { super.onStart() // 设置透明背景和半透明蒙层 dialog?.window?.apply { setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) val params = attributes params.dimAmount = 0.5f // 蒙层透明度,0-1之间调整 attributes = params } } }
3. 替换原有长按回调代码
首先让你的UserListFragment实现UserOptionDialogFragment.OnOptionClickListener接口,实现对应方法:
class UserListFragment : Fragment(), UserOptionDialogFragment.OnOptionClickListener { // ... 原有其他代码 override fun onEditUser(userId: Long) { // 处理编辑逻辑,比如跳转到编辑页 findNavController().navigate( UserListFragmentDirections.actionUserListFragmentToIncreaseMoneyFragment(userId) ) } override fun onDeleteUser(userId: Long) { // 调用原有删除逻辑 deleteDialog(userId) } }
然后替换原长按位置的Toast:
val mUserAdapter = UserAdapter() mUserAdapter.setOnclickListener(AdapterListener({ if (it != 0L) this.findNavController().navigate( UserListFragmentDirections.actionUserListFragmentToIncreaseMoneyFragment(it) ) Log.d("TAG", "navTeat $it ") }, { deleteDialog(it) } ) { userId -> // 假设长按回调返回当前点击的用户ID,你需要根据实际适配器逻辑拿到对应用户名 // 从数据库/适配器当前Item获取用户名 val userName = mUserAdapter.currentList.first { it.id == userId }.name // 显示弹窗 UserOptionDialogFragment.newInstance(userId, userName) .show(childFragmentManager, "UserOptionDialog") }
内容的提问来源于stack exchange,提问作者AmirHossein
相关产品推荐
相关产品推荐

