【问题标题】:Can't extend android.widget.MediaController to override setSystemUiVisibility无法扩展 android.widget.MediaController 以覆盖 setSystemUiVisibility
【发布时间】:2017-04-05 07:01:02
【问题描述】:

我正在开发我的第一个 Android 应用。它被设计成沉浸式的,并在所有 Activity 上隐藏 NavigationBar,同时通过 ActionBar 提供自己的内部导航。

我承诺为此应用程序使用默认的 MediaController 视图。我通过android.widget.VideoView 使用android.widget.MediaController 作为全屏视频活动的MediaController。我还使用了android.widget.MediaController 的扩展,它通过android.media.MediaPlayer 实现了MediaController.MediaPlayerControl 的非全屏音频活动。

在调查了android.widget.MediaController 源之后,它在当前活动的顶部将自己显示为一个新窗口中的 FrameLayout。每当要显示 MediaController 时,它都会通过调用下面的 mWindowManager.addView(mDecor, mDecorLayoutParams); 将自己添加到带有一组特定布局参数的窗口中。

public void show(int timeout) {
    if (!mShowing && mAnchor != null) {
        setProgress();
        if (mPauseButton != null) {
            mPauseButton.requestFocus();
        }
        disableUnsupportedButtons();
        updateFloatingWindowLayout();
        mWindowManager.addView(mDecor, mDecorLayoutParams);
        mShowing = true;
    }
    updatePausePlay();

    // cause the progress bar to be updated even if mShowing
    // was already true.  This happens, for example, if we're
    // paused with the progress bar showing the user hits play.
    post(mShowProgress);

    if (timeout != 0 && !mAccessibilityManager.isTouchExplorationEnabled()) {
        removeCallbacks(mFadeOut);
        postDelayed(mFadeOut, timeout);
    }
}

此调用的结果是重置此窗口的 SystemUiVisibility,应用退出沉浸式模式,显示 NavigationBar。

我遇到的问题是这个类的每个变量都是私有的,就像大多数方法一样。任何私有变量都有零个 getter 或 setter。因此,我无法更改 show 方法与其变量的交互。

在扩展 MediaController 类时,我只能重写 show 方法来立即调用 hideNavigation。但是,每次显示控制器时,NavigationBar 仍会短暂出现在屏幕上!这不是我喜欢的解决方案。

// MediaController implementation
@Override
public void show(int timeout) {
    super.show(timeout);

    // hide navigation
    hideNavigation();
}

// hide navigation
public void hideNavigation() {

    // get root view
    View rootView = this.getRootView();

    // options
    final int options =
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_FULLSCREEN |
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    ;

    // set visibility options
    rootView.setSystemUiVisibility(options);
}

因此,鉴于我无法正确扩展该类,由于它的私有设计,我想用我自己的完全替换它,使用原始代码中的大部分代码,只使用受保护的变量和方法而不是私人的。

这种方法的问题是我无法将import com.android.internal.policy.PhoneWindow; 添加到我的Android Studio 项目中。如何在我的 Gradle 构建中包含这个包?

compile 'com.android.internal.policy:phonewindow:1.0'

我需要进行哪些更改才能使其正常工作?或者,这是不可能的吗?

此外,我可以看到无法识别对android.view.accessibility.AccessibilityManagergetInstance(Context context) 方法的调用,因此这也会阻止我复制此类。

为什么这个方法不可用?

如果有其他方法可以强制阻止窗口更改其 SystemUiVisibility 选项,或者有其他方法可以在不复制整个类的情况下扩展 show 方法,那就更好了!

任何指导将不胜感激。

【问题讨论】:

    标签: java android android-gradle-plugin mediacontroller


    【解决方案1】:

    我现在面临同样的问题。我想对 MediaController 类进行更改。

    我虽然在类中存在一个错误,导致它不会导入 PhoneWindow,并且 getInstance(context) 抛出错误,但现在我看到这是一种保护代码的方法。

    我在 stackoverflow 上找到了这个答案:

    由于 com.android.internal.telefony 属于 Android 的内部(或隐藏)API,您不能直接导入它。但是有一些方法可以与他们合作。我建议您查看 thisthis 以了解如何通过反射使用电话。

    这与 PhoneWindow 类无关,但我认为可以对此类进行类似的操作。我还没有尝试过,但也许你可以?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多