Android自定义侧滑Item

这篇具有很好参考价值的文章主要介绍了Android自定义侧滑Item。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android自定义侧滑Item,Android,android,giteeAndroid自定义侧滑Item,Android,android,gitee

源码地址:https://github.com/LanSeLianMa/CustomizeView/tree/master/cehuaitem

使用方式一: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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.test.festec.cehuaitem.widget.SideslipContainer
        android:id="@+id/sideslip_container01"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        app:option_width="65dp">

        <com.test.festec.cehuaitem.widget.SideslipContent
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:background="@color/d5"
                android:paddingTop="20dp"
                android:textAlignment="center"
                android:textSize="20sp"
                android:text="content"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </com.test.festec.cehuaitem.widget.SideslipContent>

        <com.test.festec.cehuaitem.widget.SideslipOption
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/blue"
            android:tag="add"
            android:text="增加" />

        <com.test.festec.cehuaitem.widget.SideslipOption
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/orange"
            android:tag="edit"
            android:text="编辑" />

        <com.test.festec.cehuaitem.widget.SideslipOption
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/red"
            android:tag="delete"
            android:text="删除" />

    </com.test.festec.cehuaitem.widget.SideslipContainer>


</LinearLayout>

Activity中监听

class MainActivity : Activity() {

    private lateinit var binding: ActivityMainBinding

    private var options = mutableListOf("增加", "编辑", "删除")
    private var optionBg = mutableListOf(R.color.blue, R.color.orange, R.color.red)

    @SuppressLint("UseCompatLoadingForDrawables")
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.sideslipContainer01.addOnClickListener(object : SideslipContainer.SideslipContainerOnClick {

            override fun optionOnClick(optionTag: Any) {
                Toast.makeText(this@MainActivity,"optionTag:$optionTag", Toast.LENGTH_SHORT).show()
                binding.sideslipContainer01.sideslipRecover()
            }

            override fun contentOnClick() {
                Toast.makeText(this@MainActivity,"content", Toast.LENGTH_SHORT).show()
                binding.sideslipContainer01.sideslipRecover()
            }

        })

    }

}

使用方式二:代码方式使用

先定义一个容器文章来源地址https://www.toymoban.com/news/detail-645236.html

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <LinearLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" />


</LinearLayout>

Activity中动态添加

class MainActivity : Activity() {

    private lateinit var binding: ActivityMainBinding

    private var options = mutableListOf("增加", "编辑", "删除")
    private var optionBg = mutableListOf(R.color.blue, R.color.orange, R.color.red)

    @SuppressLint("UseCompatLoadingForDrawables")
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 创建侧滑容器,配置基础参数
        val sideslip = SideslipContainer(this, DensityUtil.dp2px(this, 65f))
        val layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            DensityUtil.dp2px(this, 70f)
        )
        sideslip.layoutParams = layoutParams

        // 创建侧滑内容
        val content = SideslipContent(this).apply {
            background = resources.getDrawable(R.color.black,null)
        }

        // 加入侧滑容器中
        sideslip.addView(content)

        // 创建选项卡,并加入侧滑容器中
        options.forEachIndexed { index, str ->
            val option = SideslipOption(this,str)
            option.text = str
            option.background = resources.getDrawable(optionBg[index], null)
            sideslip.addView(option)
        }

        // 点击监听
        sideslip.addOnClickListener(object : SideslipContainer.SideslipContainerListener {
            override fun optionOnClick(optionTag: Any) {
                Log.e("TAG","optionTag:$optionTag")
            }

            override fun contentOnClick() {
                Log.e("TAG","content")
            }
        })

        binding.container.addView(sideslip)

    }

}

使用方式三:结合RecyclerView使用

重写LayoutManager

// 重写LayoutManager,动态让RecyclerView 禁止/恢复 Y轴滚动
open class CustomLinerLayoutManager(context: Context) : LinearLayoutManager(context) {

    private var isScrollEnabled = true

    fun getEnabled(): Boolean {
        return isScrollEnabled
    }

    fun setScrollEnabled(flag: Boolean) {
        isScrollEnabled = flag
    }

    override fun canScrollVertically(): Boolean {
        return isScrollEnabled && super.canScrollVertically();
    }

}

重写RecyclerView

class MyRecyclerView : RecyclerView {

    constructor(context: Context) : super(context)
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)

    init {
        addOnScrollListener(object : RecyclerView.OnScrollListener() {

            /**
             *
             * public static final int SCROLL_STATE_IDLE = 0;  :  RecyclerView 当前未滚动。
             *
             * public static final int SCROLL_STATE_DRAGGING = 1;  :  RecyclerView 当前正在被外部输入(例如用户触摸输入)拖动。
             *
             * public static final int SCROLL_STATE_SETTLING = 2;  :  RecyclerView 当前正在动画到最终位置,而不是在外部控制。
             */
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    childrenRecover()
                }
            }
        })
    }

    // view初始化
    private var viewInit = false

    // 上一会触摸的子View
    var originalChild: SideslipContainer? = null

    // 当前触摸的子View
    var currentChild: SideslipContainer? = null

    private var customLayoutManager: CustomLinerLayoutManager? = null

    private var childMoveCallback = object : ChildOnTouchCallback {
        override fun currentChildMove() {
            childrenRecover()
        }

        override fun originalChild(originalSideslip: SideslipContainer?) {
            originalChild = originalSideslip
        }

        override fun currentChild(currentContainer: SideslipContainer?) {
            currentChild = currentContainer
        }

        override fun listStopYScroll() {
            // Log.e("TAG", "List停止滚动")
            if (customLayoutManager!!.getEnabled()) {
                customLayoutManager?.setScrollEnabled(false)
            }
        }

        override fun listRecoverYScroll() {
            // Log.e("TAG", "List恢复滚动")
            if (!(customLayoutManager!!.getEnabled())) {
                customLayoutManager?.setScrollEnabled(true)
            }
        }

    }

    // 子View恢复
    private fun childrenRecover() {
        children.forEach {
            (it as SideslipContainer).sideslipRecover()
        }
    }

    override fun onViewAdded(child: View?) {
        // Log.e("TAG","onViewAdded")
        val sideslipContainer = (child as SideslipContainer)
        sideslipContainer.addOnChildMoveCallback(childMoveCallback)
    }

    // 当复用item,彻底超出屏幕,不可见时执行
    override fun onViewRemoved(child: View?) {
        // Log.e("TAG","onViewRemoved")
        (child as SideslipContainer).sideslipStateRest()
    }

    override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
        // Log.e("TAG","onWindowFocusChanged")
        super.onWindowFocusChanged(hasWindowFocus)
        if (!viewInit) {
            customLayoutManager = (layoutManager as CustomLinerLayoutManager)
        }
        viewInit = true
    }

    interface ChildOnTouchCallback {

        // 有子View侧滑了
        fun currentChildMove()

        // 上一个触摸的子View
        fun originalChild(originalSideslip: SideslipContainer?)

        // 当前触摸的子View
        fun currentChild(currentContainer: SideslipContainer?)

        // 列表停止Y轴滚动
        fun listStopYScroll()

        // 列表恢复Y轴滚动
        fun listRecoverYScroll()

    }

}

RecyclerView适配器

class MyListAdapter(
    var context: Context,
    var data: MutableList<Info>
) : RecyclerView.Adapter<MyListAdapter.MyViewHolder>() {

    private var options = mutableListOf("增加", "编辑", "删除")
    private var optionBg =
        mutableListOf(R.color.blue, R.color.orange, R.color.red)

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)
        val sideslip = sideslipContainer(itemView)
        return MyViewHolder(sideslip)
    }

    @SuppressLint("UseCompatLoadingForDrawables", "ResourceAsColor")
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val sideslip = holder.itemView as SideslipContainer

        // 根据不同权限,添加不同的选项卡
        val optionsView = mutableListOf<SideslipOption>()
        if (data[position].level == 0) {
            optionsView.clear()
        } else if (data[position].level == 1) {
            val option = SideslipOption(context, options[1])
            option.text = options[1]
            option.background = context.resources.getDrawable(optionBg[1], null)
            optionsView.add(option)
        } else {
            options.forEachIndexed { index, str ->
                val option = SideslipOption(context, str)
                option.text = str
                option.background = context.resources.getDrawable(optionBg[index], null)
                optionsView.add(option)
            }
        }
        sideslip.addMultipleOption(optionsView)

        // 点击回调
        sideslip.addOnClickListener(object : SideslipContainer.SideslipContainerOnClick {
            override fun optionOnClick(optionTag: Any) {
                Toast.makeText(context,"${holder.adapterPosition} -- optionTag:$optionTag",Toast.LENGTH_SHORT).show()
                sideslip.sideslipRecover()
            }

            override fun contentOnClick() {
                Toast.makeText(context,"${holder.adapterPosition} - content",Toast.LENGTH_SHORT).show()
                sideslip.sideslipRecover()
            }
        })
        holder.idTv.text = data[position].id.toString()
        holder.titleTv.text = data[position].title
        holder.describeTv.text = data[position].describe
    }

    override fun getItemCount(): Int {
        return data.size
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun sideslipContainer(itemView: View): SideslipContainer {
        // 创建侧滑容器,配置基础参数
        val sideslip = SideslipContainer(context)
        sideslip.setOptionWidth(DensityUtil.dp2px(context, 65f))

        val layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            DensityUtil.dp2px(context, 70f)
        )
        sideslip.layoutParams = layoutParams

        // 创建侧滑内容
        val content = SideslipContent(context)
        content.addView(itemView)

        // 加入侧滑容器中
        sideslip.addView(content)

        // 创建选项卡,并加入侧滑容器中
        // options.forEachIndexed { index, str ->
        //    val option = SideslipOption(context, str)
        //    option.text = str
        //    option.background = context.resources.getDrawable(optionBg[index], null)
        //    sideslip.addView(option)
        // }
        return sideslip
    }

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var idTv: TextView
        var titleTv: TextView
        var describeTv: TextView

        init {
            idTv = itemView.findViewById(R.id.id_tv)
            titleTv = itemView.findViewById(R.id.title_tv)
            describeTv = itemView.findViewById(R.id.describe_tv)
        }
    }
}

Activity中绑定数据

class ListActivity : Activity() {

    private lateinit var binding: ListLayoutBinding

    private val data: MutableList<Info> = mutableListOf(
        Info(0, "title", "content", 2),
        Info(1, "title", "content", 1),
        Info(2, "title", "content", 2),
        Info(3, "title", "content", 2),
        Info(4, "title", "content", 2),
        Info(5, "title", "content", 1),
        Info(6, "title", "content", 1),
        Info(7, "title", "content", 2),
        Info(8, "title", "content", 2),
        Info(9, "title", "content", 1),
        Info(10, "title", "content", 1),
        Info(11, "title", "content", 2),
        Info(12, "title", "content", 2),
        Info(13, "title", "content", 1),
        Info(14, "title", "content", 1),
        Info(15, "title", "content", 2),
        Info(16, "title", "content", 2),
        Info(17, "title", "content", 2),
        Info(18, "title", "content", 2),
        Info(19, "title", "content", 1),
        Info(20, "title", "content", 2),
        Info(21, "title", "content", 1),
        Info(22, "title", "content", 2),
        Info(23, "title", "content", 2),
        Info(24, "title", "content", 2),
        Info(25, "title", "content", 1),
        Info(26, "title", "content", 2),
        Info(27, "title", "content", 1),
        Info(28, "title", "content", 2),
        Info(29, "title", "content", 2),
        Info(30, "title", "content", 2),
        Info(31, "title", "content", 1),
        Info(32, "title", "content", 1),
        Info(33, "title", "content", 2),
        Info(34, "title", "content", 2),
        Info(35, "title", "content", 1),
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ListLayoutBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val adapter = MyListAdapter(this, data)
        val linearLayoutManager = CustomLinerLayoutManager(this)
        binding.root.layoutManager = linearLayoutManager
        binding.root.adapter = adapter
    }

}

到了这里,关于Android自定义侧滑Item的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android:RecyclerView自由拖动item

    原生就自带有可拖动item的工具:ItemTouchHelper 看下效果: 可拖动RecyclerView预览效果 接下来我们看如何使用。 其中判断条件中的item.isMovable这边是记录该item是否可以拖动,也可以换成其他判断条件比如根据位置判断等。 另外,需要留意一点,如果你是在onBindViewHolder中有设置点

    2024年01月23日
    浏览(47)
  • Android Recyclerview的item间距实现

    Recyclerview中,提供了一个方法 addItemDecoration 给我们用于设置item的分割线 下面提供几个常见的分割线效果 注: 下面的 SizeUtils 是AndroidUtilCode此库里的工具类,需要添加依赖,也可以自行修改封装的方法(主要是将dp单位转为px) 以下代码已封装在我的库中stars-one/XAndroidUtil: 封装自己常

    2024年02月05日
    浏览(59)
  • Android LinearLayout快速设置每个item间隔

    原文地址: Android LinearLayout快速设置每个item间隔 平常使用LinearLayout的时候,有时候会需要对每个item设置间距,但是每个item都加上margin的方法实在有些繁琐 因为之前是在写JavaFx程序,里面的Vbox或Hbox都会提供一个Space的参数,可以用来快速设置每个item之间的间距 而Android这边,是没看

    2024年02月17日
    浏览(45)
  • 【Android】RecycleView 将指定item滚动置顶(kotlin)

    item有三种情况: 情况1:在可见范围之前 item在第一个可见item之前,直接用smoothScrollToPosition,则当该item移动到可见范围时,它就在RecyclerView顶部 情况2:在可见范围内 tem在可见范围内(即在第一个可见item之后,最后一个可见item之前),这时scrollToPosition失效,需要手动计算

    2024年02月04日
    浏览(71)
  • Android开发:RecyclerView获取item位置的几种方法比较

            当使用 RecyclerView 来展示列表数据时,获取 item 的位置是一个常见的需求。RecyclerView 提供了多种获取 item 位置的方法,包括 getAdapterPosition() 、 getBindingAdapterPosition() 、 getAbsoluteAdapterPosition() 等等。这些方法的实现原理和返回值有所不同,因此在实际使用时需要根据

    2023年04月20日
    浏览(78)
  • android,Compose,消息列表和动画(点击item的时候,就会删除)

    Compose,消息列表和动画(点击item的时候,就会删除) 案例二:

    2024年02月13日
    浏览(43)
  • Android NestedScrollView包裹RecyclerView高度撑满所有item,kotlin

    Android NestedScrollView包裹RecyclerView高度撑满所有item,kotlin 当用NestedScrollView包裹RecyclerView后,   然而设置: 会使得RecyclerView加载完成所有itemCount的数理,撑满整个RecyclerView高度,这深深改变了RecyclerView只加载显示当前屏幕可见区域的特性,此时RecyclerView一次性加载全部item。

    2024年02月16日
    浏览(46)
  • Android中实现RecyclerView,并对item及其多个子控件的点击事件监听

    目录 背景 实现RecyclerView 第一步、 新建item的xml 第二步、在activity的布局中引入 RecyclerView 第三步、新建一个adapter   第四步、在activity中初始化绑定adapter即可 实现item及其多个子组件点击事件监听 第一步、 适配器中创建监听对象 第二步、适配器中绑定监听item和子组件 第三

    2024年02月19日
    浏览(53)
  • Android RecyclerView实现选中Item变色的最精简高效实现(绝不会出现点击时其它item偶尔也被选中现象)

    效果:  核心代码如下: 代码超精简,试一下您就知道了。跟网上其它的教程不同,绝不会出现点击时其它item偶尔也被同步选中改变颜色导致乱串的现象

    2024年02月11日
    浏览(39)
  • 【Android】RecyclerView实现列表中的Item之间设置间距的一种方式

    RecyclerView 的 Item 默认没有间距是因为 RecyclerView 是一个高度自定义的控件,它的目标是提供一个高效灵活的列表展示,并且适应各种不同的布局需求。 为了让开发者能够充分自定义列表项的布局和样式,RecyclerView 没有默认设置项来添加 item 之间的间距。这样设计的好处是,

    2024年02月13日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包