Android中的浮动视频视图

Posted

技术标签:

【中文标题】Android中的浮动视频视图【英文标题】:Floating Video View in Android 【发布时间】:2019-11-17 22:36:50 【问题描述】:

我想要做的是:

我有一个带有滚动视图的片段,顶部有视频。我想要实现的是让视频在我滚动时浮动。

与此链接类似的行为:https://www.independentarabia.com/jsonfeed/api/v2/node/34291

我在图片模式下查看图片但没有运气

谁能告诉我如何实现这种行为?

【问题讨论】:

【参考方案1】:

如果有人想做这样的事情: 我提到了jw播放器库:

scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener  v, _, scrollY, _, oldScrollY ->
            x = 0
            if (scrollY > 200) 
                if (!mPlayerContainer.isMovable) 
                    movable = false
                    x = 2
                 else 
                    x = 0
                    val momentView = v.getChildAt(v.childCount - 1)

                val diff = (momentView.bottom - (scroll.height + scroll
                    .scrollY))

                if (diff < 50) 
                    val layoutParamsNew =
                        RelativeLayout.LayoutParams(mPlayerContainer.width, mPlayerContainer.height)
                    layoutParamsNew.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
                    layoutParamsNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                    val displayMetrics = resources.displayMetrics
                    layoutParamsNew.setMargins(
                        0,
                        0,
                        (displayMetrics.density * 16).roundToInt(),
                        (displayMetrics.density * 16).roundToInt()
                    )
                    mPlayerContainer.layoutParams = layoutParamsNew
                 else 
                    val layoutParamsNew =
                        RelativeLayout.LayoutParams(mPlayerContainer.width, mPlayerContainer.height)
                    layoutParamsNew.addRule(RelativeLayout.CENTER_VERTICAL)
                    layoutParamsNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                    val displayMetrics = resources.displayMetrics
                    layoutParamsNew.setMargins(
                        0,
                        0,
                        (displayMetrics.density * 16).roundToInt(),
                        (displayMetrics.density * 16).roundToInt()
                    )
                    mPlayerContainer.layoutParams = layoutParamsNew
                
            
         else if (scrollY < 200 && mPlayerContainer.isMovable) 
            movable = true
            x = 1
        
        if (x != 0) 
            toggleMovablePlayer()
        
    )
 private fun toggleMovablePlayer() 
    if (!movable) 
        // Set the player container to movable, in order to intercept touch events.
        mPlayerContainer.isMovable = true

        // Disable fullscreen rotation handling on the JW Player.
        mPlayerView!!.setFullscreen(mPlayerView!!.fullscreen, false)

        // Disable controls.
        mPlayerView!!.controls = false
        if (mPlayerState != PlayerState.PLAYING && mPlayerState != PlayerState.BUFFERING) 
            // Start playback in case the user hasn't done this yet, since we don't want to have
            // a movable player that does not play anything...
            mPlayerView!!.play()
        

        // Scale the player.
        mInitialLayoutParams = mPlayerContainer.layoutParams
        val newWidth = (mPlayerContainer.width / SCALING_FACTOR)
        val newHeight = (mPlayerContainer.height / SCALING_FACTOR)
        val layoutParams = RelativeLayout.LayoutParams(newWidth.toInt(), newHeight.toInt())

        // Position the player in the right bottom corner.
        mPlayerContainer.layoutParams = getInitialMovablePlayerLayoutParams(layoutParams)

        // Set an onTouchListener on the player which handles MotionEvents.
        mPlayerContainer.setOnTouchListener(View.OnTouchListener  v, event ->
            if (v.id == R.id.player_container) 
                val layoutParams = v.layoutParams as RelativeLayout.LayoutParams
                when (event.action) 
                    MotionEvent.ACTION_DOWN ->
                        // Notify the MovablePlayerLayout that we started consuming
                        // events in order to receive ACTION_MOVE events.
                        return@OnTouchListener true
                    MotionEvent.ACTION_MOVE -> 
                        var topMargin = event.rawY.toInt() - v.height
                        var leftMargin = event.rawX.toInt() - v.width / 2

                        // Make sure that the view can not go "out of bounds"
                        if (topMargin < 0) 
                            // Out of bounds: TOP
                            topMargin = 0
                        
                        if (topMargin > mContentContainer.height - mPlayerContainer.height) 
                            // Out of bounds: BOTTOM
                            topMargin = mContentContainer.height - mPlayerContainer.height
                        
                        if (leftMargin < 0) 
                            // Out of bounds: LEFT
                            leftMargin = 0
                        
                        if (leftMargin > mContentContainer.width - mPlayerContainer.width) 
                            // Out of bounds: RIGHT
                            leftMargin = mContentContainer.width - mPlayerContainer.width
                        

                        layoutParams.topMargin = topMargin
                        layoutParams.leftMargin = leftMargin

                        // Make sure the align rules have been removed.
                        layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
                        layoutParams.removeRule(RelativeLayout.CENTER_VERTICAL)
                        layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                        layoutParams.rightMargin = 0
                        layoutParams.bottomMargin = 0
                        // Set the new layout parameters
                        v.layoutParams = layoutParams
                        return@OnTouchListener true
                    
                
            
            false
        )
     else 
        // Disable the movable property of the MovableViewLayout.
        mPlayerContainer.isMovable = false
        // Restore the initial layout parameters.
        mPlayerContainer.layoutParams = mInitialLayoutParams
        // Remove the onTouchListener.
        mPlayerContainer.setOnTouchListener(null)
        // Re-enable the controls.
        mPlayerView!!.controls = true
        // Re-enable fullscreen rotation handling, and go to fullscreen if we're in landscape mode.
        mPlayerView!!.setFullscreen(
            resources.configuration.orientation === Configuration.ORIENTATION_LANDSCAPE,
            true
        )
    

  private fun setInitialLayoutParams() 
    val displayMetrics = resources.displayMetrics
    if (resources.configuration.orientation === Configuration.ORIENTATION_PORTRAIT) 
        /*mPlayerContainer.layoutParams = RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, displayMetrics.widthPixels / 16 * 9
        ) // 16:9*/
        mPlayerContainer.layoutParams = RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                200f,
                resources.displayMetrics
            ).toInt()
        )
     else 
        // We need to use height to calculate a 16:9 ratio since we're in landscape mode.
        mPlayerContainer.layoutParams = RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, displayMetrics.heightPixels / 16 * 9
        ) // 16:9
        // Toggle fullscreen, since we're in landscape mode.
        mPlayerView!!.setFullscreen(true, true)
    


/**
 * Positions the movable player to the right bottom corner.
 *
 * @param layoutParams
 * @return
 */
private fun getInitialMovablePlayerLayoutParams(layoutParams: RelativeLayout.LayoutParams): RelativeLayout.LayoutParams 
    layoutParams.addRule(RelativeLayout.CENTER_VERTICAL)
    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
    val displayMetrics = resources.displayMetrics
    layoutParams.setMargins(0, 0, Math.round(displayMetrics.density * 16), Math.round(displayMetrics.density * 16))
    return layoutParams

【讨论】:

以上是关于Android中的浮动视频视图的主要内容,如果未能解决你的问题,请参考以下文章

材料设计中的Android EditText视图浮动提示

Android:使用 JW Player SDK 实现浮动视频播放器(如 YouTube android 应用)

Android 浮动视图(在其他视图之上)

在列表视图前浮动一个按钮

Android - 创建带有浮动标题的列表视图

另一个线程中的 Android 视频视图 & android 2.1 的问题