MediaController position inside fragment

I noticed a problem regarding the position of a MediaController for a VideoView inside a Fragment . Here is a screenshot of how it looks on the Nexus 7 running Android 4.3: Screenshot of app with MediaController on 4.3

And here is a screenshot of the application on the Nexus 7 running Android 4.2.2: enter image description here

As you can see, the position of the MediaController is in the middle of my activity by API 17 or lower (tested on another tablet with 4.1.2). I noticed that the size of the MediaController is correct.

My fragment is shown in FrameLayout, the width of which is determined by its weight (0.6 here), therefore not by the specific dpi value.

I checked the source code of MediaController on Grepcode and compared version 4.3 with code 4.2.2 and there are minor changes with LayoutParams, but I can’t find a way to make this work.

I initialize my VideoView and MediaController in onActivityCreated () of my fragment

 mMediaController = new MediaController(getActivity()); mMediaController.setAnchorView(videoView); videoView.setMediaController(mMediaController); 

Does anyone know how I can position it correctly?

+6
source share
1 answer

First of all, we need a special MediaController to change its strange behavior in android to 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(); px = anchorPos[0] + (mAnchor.getWidth() - p.width) / 2; py = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight(); mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); } catch (Exception e) { e.printStackTrace(); } } } } 

Then just replace the MediaController in the CustomMediaController variable declaration, and everything will be done. The reason is that Android code up to 4.3 was listened to. We use reflection for the correct position in the show () method.

Tested with android 4.0.

+2
source

Source: https://habr.com/ru/post/955565/


All Articles