The question has been asked before here, yet I would like to provide a little more information.
The YouTubePlayerView often gives a black outline when scrolling, this can happen after pausing and changing rotation.
This appears to happen when I scroll and it gets overlaid, so it pauses (to prevent that controls get hidden). The pausing isn't a problem since the user isn't watching the video but the black screen is.
This happens on a Galaxy Tab 2 running Android 4.0.3, also on a Xperia T on 4.1.2, on a One X running 4.2.2 and Desire running 2.2.2 does the problem not occur.
Some more info:
The video-image that is paused appears to be stretching (On Xperia T) with the top of the screen while scrolling down. The black field starts scrolling over other content when it looks like it reached its minimum size.
Warning text:
YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is not contained inside its ancestor android.widget.ScrollView#41290ca0. The distances between the ancestor's edges and that of the YouTubePlayerView is: left: 20, top: 0, right: 20, bottom: -11 (these should all be positive).
This is my code:
<TextView
android:id="#+id/textView"
android:gravity="center"
android:textSize="25sp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="#string/header" />
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp" >
<LinearLayout
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" > <!-- In a linear layout so it is possible to set it in the middle -->
<com.google.android.youtube.player.YouTubePlayerView
android:id="#+id/youtubeplayer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" >
</com.google.android.youtube.player.YouTubePlayerView>
</LinearLayout>
</ScrollView>
So my question is, is there a way to get rid or prevent the black patch from showing?
Currently I have a large workaround, when the user starts scrolling, the youtubeplayer will be released and a image with a play button will take its place, when the user presses the button the youtubeplayer will reinitialize and continue the video.
Actually there is a workaround for this problem. You need to put a listener to your ScrollView and catch the Y distance. When the Y distance is close to the height of the YoutubePlayerView you need to pause the video.
scrollView.getViewTreeObserver()
.addOnScrollChangedListener(() -> {
onScroll(scrollView.getScrollY());
}
});
private void onScroll(int position)
{
if (position>300 && position <400)
{
canPauseOnScroll=false;
}
if (canPauseOnScroll)
{
canPauseOnScroll=false;
ytHelper.getPlayer().pause();
}
}
Related
I'm working on PiP mode in my app. In fact it is working pretty fine, but I have a problem with blinking/disappearing video for a split second.
I have VideoActivity in "fullscreen"/normal mode. I'm calling enterPictureInPictureMode(); and Activity is collapsing to small PiP-frame. At the moment when animation is ending shrinking layout then video get transparent for a split second/one frame. Also exacly in this frame whole PiP-frame gets shadow under (elevation). When I touch this small PiP-frame it expands a bit to big PiP-frame (not fullscreen) and this anim is smooth, but when auto-collapse to small PiP-frame it blinks again on the end... Everytime when Activity is animating to small PiP-frame (no matter if is collapsing from big PiP-frame or fullscreen Activity) one-frame transparency-blink occurs when reaching final "small bounds". No impact to sound, video is playing steady, no calls to onPlayerStateChanged.
With newer API version we can create animation with bounds and thats how I know the video view is blinking... Using no-attribute method makes whole layout collapses and I can see blink only on area with video/player/surface view (black stripes above and below video). When I use newer method and setSourceRectHint I can see whole PiP-frame disapears without respecting black background of its parent. In fact I've added dummy View with fixed size, background color and centerInParent like PlayerView - it blinks/hides just like player when is placed below (first in parent) PlayerView layer, but placed above doesn't blink at all and is showing above PlayerView even when it disappears for split sec.
How to fix that blink or maybe though set black background, not transparent...
if (Build.VERSION.SDK_INT >= 26) {
Rect bounds = new Rect();
playerView.getVideoSurfaceView().getDrawingRect(bounds);
int toTop = (playerView.getMeasuredHeight() - bounds.height()) / 2,
toLeft = (playerView.getMeasuredWidth() - bounds.width()) / 2;
bounds.top += toTop;
bounds.left += toLeft;
bounds.bottom += toTop;
bounds.right += toLeft;
enterPictureInPictureMode(new PictureInPictureParams.Builder().
setSourceRectHint(bounds).
setAspectRatio(new Rational(bounds.width(), bounds.height())).
build());
} else
enterPictureInPictureMode();
xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black">
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/activity_video_player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="#android:color/black"
app:controller_layout_id="#layout/exo_custom_control_view"
app:fastforward_increment="10000"
app:rewind_increment="10000"
app:show_timeout="100" />
...
PS. Above problem also appears when using usual VideoView played in WebView and got into fullscreen by VideoEnabledWebChromeClient. But in this case blink reveals for a split second part of WebViews content
edit: I've just found a workaround for blinking ExoPlayer - by replacing SurfaceView with TextureView, adding app:surface_type="texture_view" - but I'm reading that TextureView is a bit less efficient and also this is not fixing VideoView blink (fullscreen from WebView)
edit2: can confirm blinks on Android 8 (Xiaomi) and 9 (Pixel)
I'm trying to make an interactable imageView by setting some invisible image buttons on top of it, the user can then click different parts of the image and do things with it, the problem is that i need this image buttons to be in very exact positions in relation to the image view, if the phone size varies even a little, the image buttons will get off the positon i want them to be.
The xml where the image view is:
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".fragments.Offroad18nitro4wdbuggy_frontFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="OffRoad 1/8 nitro 4WD buggy front" /> <!-- Here just to show the programmer which fragment is showing -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_centerHorizontal="true">
<ImageView
android:id="#+id/ivLosi4_offroad18nitro4wdbuggy_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="#drawable/losi4_18scale_front"/>
<ImageButton
android:id="#+id/ibTest"
android:layout_width="50dp"
android:layout_height="41dp"
android:alpha="0"
android:background="#color/colorGreen"
android:layout_alignParentEnd="true"
android:layout_marginEnd="40dp"
android:layout_marginTop="5dp"/>
</RelativeLayout>
As you can see in the second screenshot, the image button is out of place, my phone is the Samsung Galaxy S6.
Screenshot of the image button in the exact position i want it to be
Screenshot of the app being emulated to my phone
I've dealt with this exact problem before. The workaround that I managed to accomplish is to divide the screen up into several sub-layouts so it looks like a grid of layouts. First divide the screen in half at the center point, then place an empty textview with no dimensions in the center of the top and bottom layouts, which will allow you to divide those layouts into four. Then do the same thing for those four to create sixteen if you have to. Then place your image buttons along the sides or the attached to the center point of whichever of these layouts contains your desired area.
The point is to create a grid that is fixed relative to the center of the screen. That way, if the screen size changes, the grid and the buttons attached to it will adjust accordingly. Its not a perfect solution but it worked for my purposes. Here is a link to a sample xml file from the project that I used this strategy in:
https://github.com/ribalding/AdventureAdventure/blob/master/app/src/main/res/layout/activity_kitchen.xml
When youtube player fragment nested in ScrollView I get error when rotate device to landscape:
YouTubePlayer.ErrorReason.UNAUTHORIZED_OVERLAY
And what is more interesting, is that the problem disappears when I remove ScrollView! But I can
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
/>
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerFragment"
android:id="#+id/youtubeplayerfragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
YouTubePlayer.ErrorReason.UNAUTHORIZED_OVERLAY error indicates that *Playback has been stopped due to a view overlaying the player. This means that the YouTube Player has been obscured by some other view on top of it. The YouTube API can detect it and stop the Playback.
One very common reason for this to happen is when the fragment for holding the YouTube player is embedded in a scroll view. Scroll View adds additional layer of elements can be be scrolled. For.eg the in your case. The player contained in the same declaration would detect the overlap and would eventually stop giving the above error.
I have the same problem with a YoutubePlayer inside of a ScrollView and it stops with this message:
W/YouTubeAndroidPlayerAPI: YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is not contained inside its ancestor android.widget.ScrollView{69b88e5 VFED.V... ........ 0,0-1794,1017 #7f0d0070 app:id/scrollview}. The distances between the ancestor's edges and that of the YouTubePlayerView is: left: 21, top: 196, right: 21, bottom: -164 (these should all be positive).
This happens all the time when the video is not fully visible on the screen. When it is visible completely, rotating the device works fine. To me this looks like a bug in the Youtube Android Player. I made a workaround with the following code:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// This is an ugly workaround to prevent youtube from (wrongly) thinking we have an
// overlay above the video. Having overlays is not allowed and the video would stop otherwise.
DisplayMetrics metrics = getResources().getDisplayMetrics();
int offset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, metrics);
scrollView.scrollTo(0, youtubePlayer.getView().getTop() - offset);
}
This obviously is not a good fix, because it depends on the ratio of the video and how it is shown on your display. Also your ScrollView will be scrolled to a different place after rotation (which you could re-reset manually later on).
Am I missing something, if I just have a standard TextView and set its text size over a set number the gravity to center the text stops working, see below example.
Gravity working:
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="B"
android:textSize="472sp" />
Gravity not working
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="B"
android:textSize="572sp" />
This happens on a device as well as the emulator / preview.
I would have guessed it's because the total size of the TextView including implicit padding (such as may exist) is simply larger than your screen, so the field is pinned at the top and the visible portion is forced down the screen. What happens if you put it onto a bigger display? Edit: In the 572sp example, it comes pretty close to centered in portrait mode on a tablet.
I have a PopupWindow that I am using in my Activity, and everything works fine except for the padding of the elements contained within the PopupWindow - it's much too large - literally taking up most of the small PopupWindows space. Here is the XML I use to define the PopupWindow:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/homescreen_popup_bg_levels">
<TextView
android:id="#+id/x"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textSize="12dp">
</TextView>
<TextView
android:id="#+id/y"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textColor="#FF000000">
</TextView>
</LinearLayout>
Here is a screenshot of the PopupWindow:
Any idea why the text is being padded down and to the right so much? I've tried adjusting the XML padding, etc but no luck.
Figured it out. The issue was indeed the padding of the 9-patch image - not including any meant the OS was guessing as to where to allow text, and pushing that text towards the center. Setting the padding element of the 9-patch images used for the background solved the issue.
Oh, and something else to note... when using a level list, it appears that Android is only looking at the padding of the first image that is loaded, then applying that to each and every image. As I am (was) using the levels to contain four asymmetric images (call-outs to the top left, right, bottom left, right), all of the images are getting the same padding, pixel for pixel, as the first one that gets loaded.
To solve this issue, I'm now simply setting the background image dynamically, rather than changing the level.
I would guess that your issue is the homescreen_popup_bg_levels drawable.
Try removing it and see what happens. If that's the issue, create a correct 9-patch.