自定义View封装--左滑删除(笔记)

/**
 * @describe 左滑删除
 */
class SlidingButtonView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) :
    HorizontalScrollView(context, attrs, defStyleAttr) {
    private var mTextViewDelete: TextView? = null
    private var mScrollWidth = 0
    private var mIonSlidingButtonListener: IonSlidingButtonListener? = null
    private var isOpen = false
    private var once = false
    private var isCanRemove: Boolean = false

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) {}

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (!once) {
            mTextViewDelete = findViewById(R.id.tvDelete)
            once = true
        }
    }

    override fun onLayout(
        changed: Boolean,
        l: Int,
        t: Int,
        r: Int,
        b: Int
    ) {
        super.onLayout(changed, l, t, r, b)
        if (!isCanRemove) {
            mScrollWidth =  0
            return
        }

        if (changed) {
            scrollTo(0, 0)
            //获取水平滚动条可以滑动的范围,即右侧按钮的宽度
            mScrollWidth = mTextViewDelete?.width ?: 0
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(ev: MotionEvent): Boolean {
        if (!isCanRemove) {
            return false
        }
        when (ev.action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE ->
                mIonSlidingButtonListener?.onDownOrMove(
                    this
                )
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                changeScrollX()
                return true
            }
        }
        return super.onTouchEvent(ev)
    }

    /**
     * 按滚动条被拖动距离判断关闭或打开菜单
     */
    private fun changeScrollX() {
        if (scrollX >= mScrollWidth / 2) {
            smoothScrollTo(mScrollWidth, 0)
            isOpen = true
            mIonSlidingButtonListener?.onMenuIsOpen(this)
        } else {
            smoothScrollTo(0, 0)
            isOpen = false
        }
    }

    /**
     * 打开菜单
     */
    fun openMenu() {
        if (isOpen) {
            return
        }
        smoothScrollTo(mScrollWidth, 0)
        isOpen = true
        mIonSlidingButtonListener?.onMenuIsOpen(this)
    }

    /**
     * 关闭菜单
     */
    fun closeMenu() {
        if (!isOpen) {
            return
        }
        smoothScrollTo(0, 0)
        isOpen = false
    }

    fun setSlidingButtonListener(isCanRemove: Boolean, listener: IonSlidingButtonListener?) {
        this.isCanRemove = isCanRemove
        mIonSlidingButtonListener = listener
    }

    interface IonSlidingButtonListener {
        fun onMenuIsOpen(view: View?)
        fun onDownOrMove(slidingButtonView: SlidingButtonView?)
    }

    init {
        this.overScrollMode = View.OVER_SCROLL_NEVER
    }
}

使用示例:

<?xml version="1.0" encoding="utf-8"?>
<com.xxxx.widget.SlidingButtonView
    android:id="@+id/layoutParent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="@dimen/dimen_35_dp">

        <RelativeLayout
            android:id="@+id/layout_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            //添加item的样式布局

        </RelativeLayout>

        <TextView
            android:id="@+id/tvDelete"
            android:layout_width="@dimen/dimen_60_dp"
            android:layout_height="@dimen/dimen_40_dp"
            android:layout_toRightOf="@+id/layout_content"
            android:layout_centerVertical="true"
            android:gravity="center"
            android:textColor="@color/white"
            android:text="@string/delete"
            android:contentDescription="@string/app_name"
            android:background="@color/red_700"
            android:layout_toEndOf="@+id/layout_content"
            tools:ignore="RtlHardcoded" />

    </RelativeLayout>

</com.xxxx.widget.SlidingButtonView>

适配器使用示例


class BillAdapter(layoutResId: Int = R.layout.item_bill_delete) :
    BaseQuickAdapter<ItemEntity, BaseViewHolder>(layoutResId),
    SlidingButtonView.IonSlidingButtonListener {

    private var mMenu: SlidingButtonView? = null
    private var mWidth: Int = 0

    override fun convert(holder: BaseViewHolder, item: BillItemEntity) {
		//TODO 设置item的数据
		
        //设置内容布局的宽为屏幕宽度
        val layoutContent: ViewGroup = holder.getView(R.id.layout_content)
        layoutContent.layoutParams.width = mWidth

        val slidingButtonView = holder.getView<SlidingButtonView>(R.id.layoutParent)
        val isCanRemove = item.isEdit == "1" || item.isCanRemove
        slidingButtonView.setSlidingButtonListener(isCanRemove,this)
    }

    override fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        mWidth = parent.width
        return super.onCreateDefViewHolder(parent, viewType)
    }

    /**
     * 关闭菜单
     */
    fun closeMenu() {
        mMenu?.closeMenu()
        mMenu = null
    }

    /**
     * 判断是否有菜单打开
     */
    fun menuIsOpen(): Boolean {
        return mMenu != null
    }

    /**
     * 删除菜单打开接收开始
     * @param view view
     */
    override fun onMenuIsOpen(view: View?) {
        mMenu = view as SlidingButtonView?
    }

    /**
     * 滑动或者点击item监听
     * @param slidingButtonView slidingButtonView
     */
    override fun onDownOrMove(slidingButtonView: SlidingButtonView?) {
        if (menuIsOpen()) {
            if (mMenu != slidingButtonView) {
                closeMenu()
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值