最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android?Activity通用懸浮可拖拽View封裝的思路詳解

 更新時間:2022年07月21日 09:29:48   作者:熊熊君fly  
這篇文章主要介紹了Android?Activity通用懸浮可拖拽View封裝,實現(xiàn)思路是通過封裝通用的基礎(chǔ)懸浮View,繼承通用View,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

1,背景

在開發(fā)中總會遇到一個可拖拽的懸浮View,不管是在開發(fā)中,還是在線上,都時長有這樣的控件,我們通常遇到這種情況,經(jīng)常需要自己封裝,需要耗費時間,我這邊封裝了一個可以通用的懸浮可拖拽View,這樣使用的時候,只需要傳入自己要設(shè)計的樣式和位置既可

2,思路

2.1,封裝通用的基礎(chǔ)懸浮View

設(shè)計通用的父View

1,傳入的childView是可以自定義layout,可以傳入任何樣式

childView = setChildView()

2,可以設(shè)置初始的位置

layoutParams = setChildInitLayoutParams()

3,可以修改自定義view控件

setChildAction(childView)

4,提供點擊事件處理

protected abstract fun setEventClick()

子view繼承父view就可以實現(xiàn)自己想要的功能了

abstract class AbsParentDragView : FrameLayout, View.OnTouchListener {

    //需要添加的子控件
    private var childView: View? = null
    //子控件的寬
    protected var childWidth: Int = 0
    //子控件的高
    protected var childHeight: Int = 0
    //子控件的位置屬性
    lateinit var layoutParams: LayoutParams
    //點擊區(qū)域偏移量
    private var regionW: Int = 0
    //判斷是否可以移動
    private var isCanMove: Boolean = false

    private val MIN_TAP_TIME = 1000

    private val MIN_DISTANCE_MOVE = 4

    private var mState = TouchState.STATE_STOP

    private var distance: Int = 0

    private enum class TouchState {
        STATE_MOVE, STATE_STOP
    }

    constructor(context: Context) : super(context) {
        initView()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView()
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        initView()
    }


    private fun initView() {

        childView = setChildView()

        setChildAction(childView)
        addView(childView)
        setOnTouchListener(this)
        layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)

        regionW = DensityUtil.dip2px(context, 3f)
        distance = DensityUtil.dip2px(context,1f) * MIN_DISTANCE_MOVE

        post {
            childView?.width?.let {
                childWidth = it
            }
            childView?.height?.let {
                childHeight = it
            }

            layoutParams = setChildInitLayoutParams()
            initLayoutParams()
        }

    }

    protected abstract fun setChildView(): View?

    protected abstract fun setChildInitLayoutParams(): FrameLayout.LayoutParams

    protected abstract fun setChildAction(childView: View?)

    private fun initLayoutParams() {
        layoutParams.gravity = Gravity.LEFT or Gravity.TOP
        childView?.layoutParams = layoutParams
    }

    private fun updateLayoutParams(dx: Int, dy: Int) {
        layoutParams.gravity = Gravity.LEFT or Gravity.TOP
        layoutParams.leftMargin = dx - childWidth / 2
        layoutParams.topMargin = dy - childHeight / 2 - StateUtils.getStatusBarHeight(context)
        childView?.layoutParams = layoutParams
    }

    private var mStartX:Int = 0
    private var mStartY:Int = 0
    override fun onTouch(view: View, event: MotionEvent): Boolean {
        val x = event.rawX.toInt()
        val y = event.rawY.toInt()
        when(event.action){
            MotionEvent.ACTION_DOWN -> {
                mStartX = x
                mStartY = y
                if (isPointChoice(x, y)) {
                    isCanMove = true
                }
            }
            MotionEvent.ACTION_MOVE -> {
                if (Math.abs(x - mStartX) < distance
                    && Math.abs(y - mStartY) < distance) {
                    if (mState == TouchState.STATE_STOP) {
                        return true
                        //break
                    }
                } else if (mState != TouchState.STATE_MOVE) {
                    mState = TouchState.STATE_MOVE
                }

                if(isCanMove){
                    updateLayoutParams(x, y)
                }

                mState = TouchState.STATE_MOVE
            }
            MotionEvent.ACTION_UP -> {
                isCanMove = false

                if (mState != TouchState.STATE_MOVE
                    && event.eventTime - event.downTime < MIN_TAP_TIME) {
                    setEventClick()
                }

                mState = TouchState.STATE_STOP
            }
        }

        return isCanMove
    }

    protected abstract fun setEventClick()

    private fun isPointChoice(x: Int, y: Int): Boolean {
        val cLocation = IntArray(2)
        childView?.getLocationOnScreen(cLocation)

        val horizontalMatch =
            x > (cLocation[0] + regionW) && x < (cLocation[0] + childWidth + regionW)
        val verticalMatch =
            y < (cLocation[1] + childHeight + DensityUtil.dip2px(context,10f)) && y > (cLocation[1] - regionW)
       
        if (horizontalMatch && verticalMatch) {
            return true
        }

        return false
    }
}

2.1,繼承通用View

class DemoLineView(context: Context, attrs: AttributeSet?) : AbsParentDragView(context, attrs) {
    override fun setChildView(): View? {
        return LayoutInflater.from(context).inflate(R.layout.layout_draw_item, this, false)
    }


    override fun setChildInitLayoutParams(): LayoutParams {
        layoutParams.topMargin = DensityUtil.getScreenHeight(
            context
        ) - childHeight - DensityUtil.dip2px(context, 80f)
        layoutParams.leftMargin = DensityUtil.getScreenWidth(
            context
        ) - childWidth - DensityUtil.dip2px(context, 20f)
        return layoutParams
    }

    override fun setChildAction(childView: View?) {
        val tvSafeLine = childView?.findViewById<TextView>(R.id.tvSafeLine)
        tvSafeLine?.text = "設(shè)置懸浮"
    }

    override fun setEventClick() {
        Toast.makeText(context,"懸浮view",Toast.LENGTH_LONG).show()

    }

}

2.3,設(shè)計view的控制器

open class DragViewManager private constructor(context: Activity) {
    private var activity: Activity = context
    companion object : SingletonHolder<DragViewManager, Activity>(::DragViewManager)
    private lateinit var dragView: AbsParentDragView
    private val contentView = activity.window.decorView.findViewById<View>(android.R.id.content) as FrameLayout
    fun create(dragView: AbsParentDragView){
        this.dragView = dragView
        if(contentView.contains(dragView)){
            contentView.removeView(dragView)
        }
        contentView.addView(dragView)
    }
    fun show(){
        dragView.visibility = View.VISIBLE
    }
    fun dismiss(){
        dragView.visibility = View.INVISIBLE
    }
}

2.4,view的添加和使用

//創(chuàng)建出要顯示的View
DragViewManager.getInstance(this).create(new DemoLineView(this,null));
//隱藏要顯示的View
DragViewManager.getInstance(this).dismiss();
//顯示要顯示的View
DragViewManager.getInstance(this).show();

代碼鏈接地址:gitee.com/component_i…

到此這篇關(guān)于Android Activity通用懸浮可拖拽View封裝的文章就介紹到這了,更多相關(guān)Android Activity拖拽View封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

祁阳县| 龙口市| 扶绥县| 河源市| 泾川县| 徐汇区| 屯门区| 图片| 博爱县| 黄浦区| 黔江区| 贵州省| 哈巴河县| 定州市| 文昌市| 鹤山市| 克什克腾旗| 杭锦后旗| 土默特左旗| 延津县| 青河县| 榆中县| 辽宁省| 西昌市| 巴青县| 台北县| 淮北市| 萨迦县| 巴南区| 衡东县| 阿城市| 万山特区| 卫辉市| 呼图壁县| 大渡口区| 伊金霍洛旗| 兰考县| 南丹县| 玉溪市| 邵武市| 高邑县|