Android kotlin 用RecyclerView(androidx+BRVAH3.0.6)实现仿微信长按列表弹出菜单功能

一、实现效果

二、引入依赖

appbuild.gradle在添加以下代码
1、implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6',这个里面带的适配器,直接调用就即可

BaseRecyclerViewAdapterHelper简称BRVAH

Android SDK是否支持BaseRecyclerViewAdapterHelper:3.0.6
android compileSdkVersion 29
android compileSdkVersion 30
android compileSdkVersion 31
android compileSdkVersion 32
android compileSdkVersion 33

这依赖包还需要得到要添加,在Projectbuild.gradle在添加以下代码,不添加就不行

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }//加上
    }
}

2、弹出菜单:implementation 'com.noober.floatmenu:common:1.0.4'

三、实现源码

1、适配器

RvAdapter.kt

package com.example.myapplication3.adapter

import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.noober.floatmenu.R
import kotlinx.android.synthetic.main.item.view.*

class RvAdapter(layoutResId: Int = R.layout.item) :
    BaseQuickAdapter<String, BaseViewHolder>(layoutResId) {
    override fun convert(holder: BaseViewHolder, item: String) {
        holder.itemView.run {
            tv_content.text = item
        }
    }
}

item布局item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/swipe_menu_layout"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@drawable/item_bg"
    android:gravity="center">

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="菜单" />
</LinearLayout>

item样式item_bg.xml,点住前后item的颜色不同

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <stroke android:width="1.0px" android:color="@color/line" /><!--<color name="line">#fff5f5f5</color>-->

            <gradient android:angle="270.0" android:endColor="#ffe8ecef" android:startColor="#ffe8ecef" />
        </shape>
    </item>

    <item android:state_focused="true">
        <shape android:shape="rectangle">
            <gradient android:angle="270.0" android:endColor="#ffe8ecef" android:startColor="#ffe8ecef" />

            <stroke android:width="1.0px" android:color="@color/line" />
        </shape>
    </item>

    <item>
        <shape android:shape="rectangle">
            <gradient android:angle="270.0" android:endColor="#ffffffff" android:startColor="#ffffffff" />

            <stroke android:width="1.0px" android:color="@color/line" />
        </shape>
    </item>

</selector>

2、实现视图

MainActivity.kt

package com.noober.floatmenu

import android.graphics.Point
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.noober.menu.FloatMenu
import android.widget.Toast
import android.view.MotionEvent
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemLongClickListener
import com.example.myapplication3.adapter.RvAdapter
import java.util.ArrayList
import kotlinx.android.synthetic.main.activity_main.*;

class MainActivity : AppCompatActivity(), OnItemLongClickListener {

    private val point = Point()

    private val mAdapter by lazy {
        RvAdapter().apply {
            setOnItemLongClickListener(this@MainActivity)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        init()
    }

    private fun init() {
        val itemList: MutableList<String> = ArrayList()
        for (i in 0..19) {
            itemList.add("菜单$i")
        }
        val layoutManager = LinearLayoutManager(this@MainActivity)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = mAdapter
        mAdapter.setList(itemList)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            point.x = ev.rawX.toInt()
            point.y = ev.rawY.toInt()
        }
        return super.dispatchTouchEvent(ev)
    }

    override fun onItemLongClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int): Boolean {
        val floatMenu = FloatMenu(this@MainActivity)
        floatMenu.items("菜单1", "菜单2", "菜单3")
        floatMenu.show(point)
        floatMenu.setOnItemClickListener { v, position ->
            Toast.makeText(this@MainActivity,"$position", Toast.LENGTH_SHORT).show()
        }
        return true
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,这里是 Kotlin 代码示例: ```kotlin import androidx.compose.foundation.Text import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapOrLongPress import androidx.compose.foundation.gestures.waitForUpOrCancellation import androidx.compose.foundation.layout.Row import androidx.compose.material.AlertDialog import androidx.compose.material.Button import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.getSystemService import android.content.ClipboardManager import android.content.Context import android.content.Intent import android.provider.Settings import android.text.style.ClickableSpan import android.view.ContextMenu import android.view.MenuItem import android.view.View import android.widget.TextView @Composable fun LongPressText( text: String, modifier: Modifier = Modifier ) { val context = LocalContext.current val showDialog = remember { mutableStateOf(false) } val dialogText = remember { mutableStateOf("") } fun onContextMenuClick(item: MenuItem): Boolean { when (item.itemId) { 1 -> { val clipboard = getSystemService(context, ClipboardManager::class.java) val clip = android.content.ClipData.newPlainText("text", dialogText.value) clipboard?.setPrimaryClip(clip) } 2 -> { val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, dialogText.value) type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) context.startActivity(shareIntent) } } return true } fun showContextMenu(view: View, text: String) { val menu = ContextMenu(context) menu.apply { add(0, 1, 0, "复制") add(0, 2, 0, "分享") setOnMenuItemClickListener { item -> onContextMenuClick(item) } } dialogText.value = text menu.show(view, view.x.toInt(), view.y.toInt()) } val annotatedString = buildAnnotatedString { append(text) addStyle(SpanStyle(color = Color.Blue), 0, text.length) addStringAnnotations(text = text, onClick = { showDialog.value = true dialogText.value = it }, onLongClick = { val textView = TextView(context) textView.text = it textView.setTextColor(ContextCompat.getColor(context, android.R.color.black)) textView.textSize = 18f showContextMenu(textView, it) }) } Text(text = annotatedString, modifier = modifier) if (showDialog.value) { AlertDialog( onDismissRequest = { showDialog.value = false }, title = { Text(text = "闲聊") }, text = { Text(text = dialogText.value) }, confirmButton = { Button(onClick = { showDialog.value = false }) { Text("关闭") } } ) } } fun AnnotatedString.Builder.addStringAnnotations(text: String, onClick: (String) -> Unit, onLongClick: (String) -> Unit) { var startIndex = 0 var spaceIndex = text.indexOf(' ', startIndex) var newestSpace = text.length while (startIndex < text.length) { if (spaceIndex == -1) spaceIndex = text.length val word = text.substring(startIndex, spaceIndex) val clickableSpan = object : ClickableSpan() { override fun onClick(widget: View) { onClick(word) } } val range = startIndex until spaceIndex val color = Color.Blue val style = SpanStyle(color = color, textDecoration = null, background = null, fontWeight = null) addStyle(style, range.start, range.end) addStringAnnotation("Clickable", word, clickableSpan) if (word != text.substring(range.last)) { addStringAnnotation("LongClickable", word, LongClickableSpan(onLongClick)) } newestSpace = spaceIndex startIndex = spaceIndex + 1 spaceIndex = text.indexOf(' ', startIndex) } } class LongClickableSpan(private val onClick: (String) -> Unit) : ClickableSpan() { override fun updateDrawState(ds: TextPaint) { ds.color = ds.linkColor // changes the actual color of the clickable text, default is link blue ds.isUnderlineText = false // removes the underline from the clickable text, default is true } override fun onClick(view: View) { val textView = TextView(view.context) textView.text = (view as TextView).text textView.setTextColor(view.textColors) textView.textSize = view.textSize onClick(view.text.toString()) } } ``` 这个示例代码演示了如何使用 Jetpack Compose 开发 Android 应用程序,并在 Text 组件中实现按文本菜单。这里使用了 AnnotatedString 组件来渲染富文本和交互元素。同时,示例代码还包含了一个 AlertDialog 组件,用于显示与用户的交互过程。请注意,示例代码中的一些实现细节可能需要根据您的特定需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬sir哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值