我注意到有关MediaController
内VideoView
的Fragment
位置的问题。
以下是运行Android 4.3的Nexus 7的屏幕截图:
以下是运行Android 4.2.2的Nexus 7上的应用程序的屏幕截图:
如您所见,MediaController的位置在我的Activity的API 17或更低版本的中间(也已在具有4.1.2的另一台平板电脑上进行了测试)。我注意到MediaController的大小是正确的。
我的 fragment 显示在FrameLayout中,其宽度是由其重量(此处为0.6)定义的,而不是由特定的dpi值定义的。
我已经在Grepcode上检查了MediaController的源代码,并将4.3的源代码与4.2.2的代码进行了比较,并且LayoutParams进行了一些小的更改,但是我找不到一种方法来使这项工作有效。
我在 fragment 的onActivityCreated()中初始化VideoView和MediaController
mMediaController = new MediaController(getActivity());
mMediaController.setAnchorView(videoView);
videoView.setMediaController(mMediaController);
有人知道我该如何正确定位吗?
最佳答案
首先,我们将需要自定义MediaController来更改其在Android 4.3之前版本中的怪异行为
class CustomMediaController extends MediaController
{
public CustomMediaController(Context context) {
super(context);
}
public CustomMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomMediaController(Context context, boolean useFastForward) {
super(context, useFastForward);
}
@Override
public void show(int timeout) {
super.show(timeout);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < 18) //android.os.Build.VERSION_CODES.JELLY_BEAN_MR2
{
try {
Field field1 = MediaController.class.getDeclaredField("mAnchor");
field1.setAccessible(true);
View mAnchor = (View)field1.get(controller);
Field field2 = MediaController.class.getDeclaredField("mDecor");
field2.setAccessible(true);
View mDecor = (View)field2.get(controller);
Field field3 = MediaController.class.getDeclaredField("mDecorLayoutParams");
field3.setAccessible(true);
WindowManager.LayoutParams mDecorLayoutParams = (WindowManager.LayoutParams)field3.get(controller);
Field field4 = MediaController.class.getDeclaredField("mWindowManager");
field4.setAccessible(true);
WindowManager mWindowManager = (WindowManager)field4.get(controller);
int [] anchorPos = new int[2];
mAnchor.getLocationOnScreen(anchorPos);
// we need to know the size of the controller so we can properly position it
// within its space
mDecor.measure(MeasureSpec.makeMeasureSpec(mAnchor.getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(mAnchor.getHeight(), MeasureSpec.AT_MOST));
WindowManager.LayoutParams p = mDecorLayoutParams;
p.width = mAnchor.getWidth();
p.x = anchorPos[0] + (mAnchor.getWidth() - p.width) / 2;
p.y = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight();
mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
然后只需将变量声明中的MediaController替换为CustomMediaController,一切都会做。原因是4.3之前的android代码已被窃听。我们正在使用反射来纠正 show()方法中的位置。
经过android 4.0测试。
关于android - 将MediaController放置在 fragment 内,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19270251/