【问题标题】:MediaController Positioning - bind to VideoViewMediaController 定位 - 绑定到 VideoView
【发布时间】:2014-03-25 14:23:10
【问题描述】:

关于如何定位MediaController 已经有很多讨论,大多数答案是使用setAnchorView-方法。乍一看,这个解决方案似乎有效,但在我的情况下却没有。

据此PostsetAnchorView仅作为MediaController初始定位的参考,但实际上在顶部创建了一个新的浮动Window

所以我想要的是一个 真正 绑定到父 View(例如 VideoView)的 MediaController

例如,如果您在ScrollView 中有一个LinearLayout,并且您必须向下滚动到MediaController 所附加的VideoView,则MediaController 应该真正附加到此VideoView以便MediaControllerVideoView 一起滚动。

here 中讨论了另一个出现此问题的用例,其中MediaControllerViewPager 中使用。

那么如何为MediaController 实现这样的行为呢?

【问题讨论】:

    标签: android android-layout android-view android-videoview mediacontroller


    【解决方案1】:

    我最终做了一个肮脏的黑客攻击......我只是手动将视图附加到我的videoView 以实现想要的行为:

    public void onPrepared(MediaPlayer mp) {
    
                    MediaController mc = new MediaController(videoView.getContext(), false);
                    // set correct height
                    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoView.getLayoutParams();
                    params.height =  mp.getVideoHeight();
                    videoView.setLayoutParams(params);
    
                    videoView.setMediaController(mc);
                    pBar.setVisibility(View.GONE);
                    mc.show(0);
    
                    FrameLayout f = (FrameLayout) mc.getParent();
                    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                            RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                    lp.addRule(RelativeLayout.ALIGN_BOTTOM, videoView.getId());
    
                    ((LinearLayout) f.getParent()).removeView(f);
                    ((RelativeLayout) videoView.getParent()).addView(f, lp);
    
                    mc.setAnchorView(videoView);
                }
    

    此解决方案的问题在于,设置 anchorView 没有任何效果,因此点击 VideoView 不会像应有的那样隐藏/显示 MediaController

    肯定有更好的解决方案,希望有人能给我提示!

    【讨论】:

    • 太棒了,它拯救了我的一天。
    【解决方案2】:

    只是想补充一下 DERIIIFranz 的答案。我使用相同的方法将媒体控制器分配给我想要的视图并使 Hide() 和 Show() 函数正常工作我只是创建了自己的 MediaController 类并覆盖了 Hide() 和 Show() 方法作为 isShowing 属性(我在 C# 中使用 Xamarin 执行此操作,所以我不知道您在使用 Java 时会遇到什么问题)。

    我还在 VideoView 上添加了自己的点击监听器,以确保我可以自己处理 Hide() 和 Show() 事件。

    public class MyMediaController : MediaController
    {
        private bool _isShowing { get; set; } = false;
        public override bool IsShowing { get { return _isShowing; } }
    
        public override void Show ()
        {
            base.Show();
            _isShowing = true;
    
            Native.ViewGroup parent = ((Native.ViewGroup)this.Parent);
            parent.Visibility = Native.ViewStates.Visible;
        }
    
        public override void Hide ()
        {
            base.Hide();
            _isShowing = false;
    
            Native.ViewGroup parent = ((Native.ViewGroup)this.Parent);
            parent.Visibility = Native.ViewStates.Gone;
        }
    }
    

    【讨论】:

    • 以防万一这对其他人有帮助:由于我覆盖了 MediaController,因此在活动完成时或由于我需要调用 MediaPlayer.Release() 而删除了视频视图时,我收到了 InvocationException。为了避免这种情况,请确保您在自己的 Hide 和 Show 方法中调用 super.Hide() 和 super.Show()。尽管在这种情况下它们没有视觉影响,但底层类中的某些东西仍然受到影响。
    【解决方案3】:

    将 Jonathan Hockman 的答案转换为 Java 并将其添加到 DERIIIFranz 的答案中:

    public class MyMediaController extends MediaController {
    
            public MyMediaController(Context context) {
                    super(context);
            }
    
            public MyMediaController(Context context, boolean useFastForward) {
                    super (context, useFastForward);
            }
    
            public MyMediaController(Context context, AttributeSet attrs) {
                    super(context, attrs);
            }
    
            private boolean _isShowing = false;
    
            @Override
            public boolean isShowing() { return _isShowing; }
    
            @Override
            public void show() {
                    super.show();
                    _isShowing = true;
    
                    ViewGroup parent = (ViewGroup) this.getParent();
                    parent.setVisibility(View.VISIBLE);
            }
    
            @Override
            public void hide() {
                    super.hide();
                    _isShowing = false;
    
                    ViewGroup parent = (ViewGroup) this.getParent();
                    parent.setVisibility(View.GONE);
            }
    }
    

    对于视频视图:

        public void onPrepared(MediaPlayer mediaPlayer) {
                MyMediaController mediaController = new MyMediaController(videoView.getContext(), false);
    
                RelativeLayout parentLayout = (RelativeLayout) videoView.getParent();
                RelativeLayout.LayoutParams parentParams = (RelativeLayout.LayoutParams) parentLayout.getLayoutParams();
                parentParams.height = this.getHeight();
                parentLayout.setLayoutParams(parentParams);
    
                FrameLayout frameLayout = (FrameLayout) mediaController.getParent();
                RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, this.getId());
    
                ((ViewGroup)frameLayout.getParent()).removeView(frameLayout);
                parentLayout.addView(frameLayout, layoutParams);
    
                mediaController.setAnchorView(this);
                mediaController.hide();
    
                videoView.setMediaController(mediaController);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      相关资源
      最近更新 更多