everyone. I have a project where I need to display a video within a VideoView in portrait orientation, but I've been running into a weird issue for the last couple weeks. Also note, this issue only occurs the first time the VideoView is loaded with data.
This is a very stripped version of the layout:
<RelativeLayout>
<RelativeLayout>
<VideoView /> <-- W:fill_parent, H:wrap_content
</RelativeLayout>
</RelativeLayout>
Now for the actual issue: when the VideoView is first loaded with data, both its height/width fill the entire screen (minus the padding space) for less than a second (up to 3 seconds, depending on whether it's local or streaming), then it magically adjusts itself to the intended size.
Since it takes longer for videos not stored locally, I feel as if the issue has to do with the VideoView taking time to load the video, and not adjusting its boundaries correctly immediately, which is why it expands to fill the screen, then suddenly drops down to the appropriate size.
Now, I believe the reason it doesn't do that every time is because it's still using the same instance of the VideoView each time it's loaded (since it's using a ViewFlipper and not setContentView, it's not creating a new instance of it).
However, I'm loading the data into the VideoView in the same way, and I don't understand why the issue doesn't persist, which makes me think my assumption of why it's doing that is wrong.
Now for what I've tried:
I started with a width of fill_parent and height of wrap_content for both the RelativeLayout and the VideoView, which is where I noticed this problem initially. Also note: the graphic layout in Eclipse shows the same issue with these settings that I'm trying to solve: the VideoView is expanded to fill the screen, minus the padding it has).
I've tried forcing the layout to a specific pixel dimension in the XML layout (terrible, I know), and then defining new LayoutParams for the views and setting them after the video has been properly loaded.
I've tried creating a new VideoView dynamically and adding it to the layout after it's been loaded; still no luck.
And now I'm out of ideas... Anyone else have some?
And thanks in advance for your help~
EDIT:
As a workaround in the meantime, I created an onPreparedListener() for the VideoView, and keep the view hidden until the onPreparedListener is fired off. That seems to solve the problem, but I'm more curious as to why the VideoView was doing what it's doing, not necessarily just how to fix it.
Thanks again~
Related
Folks,
I cant design my android screens and see it on my emulator somehow the resolution, zoom (whatever) in the emulator is big and my layout is messed up.
The whole layout is inside a FrameLayout, the paragraph text in the emulator pic is inside a RelativeLayout, which is set to GONE after users upload rating, then LinearLayout shows up with the overall rating bar in the some place where the RelativeLayout was.
My question is why is this happening since in the preview it seems perfect and on the emulator it seems all messed.
Please see the screenshots:
Android Studio Preview:
Genymotion Emulator
It is really hard to determine what exactly is wrong without seeing your xml markup.
Possible Reasons
You gave your layouts some sort of fixed size, and therefore it appears to be fine on your markup, but whatever you are emulating on Genymotion is using a different ratio.
When you do a View.GONE, you say you are replacing a RelativeLayout with a LinearLayout. Well, do you make sure that the layout that is replaced is layoutAbove whatever that frame layout below it is?
Some layout just has some attribute, like an alignment issue, that is causing this.
Trace your steps backwards, removing one thing at a time. Get it to work with that view gone first, then add it and manipulate it after.
I'm implementing a video player with ads. Eventually, playback is paused and some ads are shown, after the ads playback is resumed.
To implement this I've done a FrameLayout with a VideoView and another View to display the ads.
When the ads break is reached I do:
videoView.pause();
videoView.setVisibility(View.GONE);
adsView.setVisibility(View.VISIBLE):
//Play ads for X time
adsView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.play();
It's fairly simple and it works fine in all devices I tried except the Nexus 7.
On the Nexus 7 when playback is resumed the video gets smaller and it doesn't fill the whole screen. It only uses aprox 1/4 of the screen.
After a lot of hours investigating I realised this only happens when I change the visibility of the VideoView. If I comment the following line //videoView.setVisibility(View.GONE); the problem disappears but I can't see the ads.
Some logs that may be relevant:
NvOsDebugPrintf BeginSequence 640x368
NvOsDebugPrintf pnvsi->nDecodeBuffers = 9
NvOsDebugPrintf Display Resolution : (640x360)
NvOsDebugPrintf Display Aspect Ratio : (128x360)
Display aspect ratio (128x360) should be the same as the display resolution (640x360) but it isn't.
Any idea?
Thanks
Not sure of the cause but there seems to be measuring error (I think there are other reports of some measuring issues on n7). View.GONE causes the views to be relaid out to account of the space that is now free from the disappearing view.
As a work around, you can avoid being relaid out -- try placing both views inside a RelativeLayout and have them completely overlap by setting fill_parent on width and height to both. Then you can use setVisibility(View.INVISIBLE) which does not cause the widgets to resize.
The top level layout in my activity is a framelayout. I have completed, debugged and tested this app and it works exactly like it should in all respects on my g1 and on various emulators. But on 3.7-inch displays running 2.1+, some imageviews packed in a linearlayout
are periodically not visible. I know that they are there because you can touch and drag them with effect in the app. So I assume somehow
they have gotten under the SurfaceView that is the main component of the app. This is apparently so even though the SurfaceView is declared in the xml prior to the LinearLayout. However, the ImageViews IN the LinearLayout are added programmatically towards the end of onCreate().
Framelayout stacks everything that is added to it, one on top of the other--the only way you will see more than one child of a frame layout is if they are smaller than the screen and are placed apart from eachother.
Oddly, sometimes the imageviews ARE visible--it is random. Anyway, I've been trying to combat this with framelayout.bringChildToFront(View v) on the linearlayout without success.
I wonder if anyone has any insight into how the behavior could be random like that, and how I should code these imageviews
to keep this from happening, and why the problem appears only to occur on 3.7 vs 3.2 inch screens (as it happens, the two 3.2-inch screens were both htc, so vendor might be factor too).
[edit] Actually, I've determined that this is a 2.2 issue, not a screen size (or even vendor) issue. Can't ensure that ImageViews added to a framelayout with a SurfaceView
in it will appear on top of the surfaceview. I ran some tests in the respective onDraw() methods and the imageviews are 'visible' (0), and nothing does anything to the alpha of the drawables, which are there as well at ondraw(). [/edit]
Any insight would be welcomed.
Ken T.
I had to draw the drawables in SurfaceView's doDraw() method, and I had to change the file names of the drawables. I think this was a case of malicious code somewhere. I had to scrap the ImageViews and transfer my touch-handling code elsewhere.
I am fairly new to android and am having some problems with a layout. Below is an approximation of what I want the layout to look like. (I would like the list to be below the screen at first so that the user can scroll down to see it.) However my code as it currently stands makes all of the views on the left only take up a quarter the screen instead of half, as depicted, even though I have all widths set to fill_parent.
Also, this layout seems to mess up the coordinate system on my custom view. Normally this wouldn't be much of an issue, but in this case I am using that view to draw a picture and the picture ends up in the wrong place. Does anybody have any idea how to resolve these issues?
Could you show the XML file you are using? This would be helpful. Also, the coordinate system of a View does not change based on the layout.
I am trying to play a videoview on top of another video view. The first video view is paused, while the second is playing. It appears to work but no second video appears on the screen (though I hear the audio and see the controls that would normally appear on top). I am assuming this is some sort of order issue. Any thoughts. By the way, I have no problem displaying other views on top of the main video view and having the video fill the background.
That won't work - the VideoView is special in the sense that it 'punches' a hole in the normal Views to allow direct access to the display pixels (or, in android terms, the 'Surface' - VideoView is a subclass of SurfaceView). You cannot layer two SurfaceViews on top of eachother - the first one that grabs the pixels (the Surface) will 'own' it. (see SurfaceHolder.Callback.surfaceCreated() / surfaceDestroyed())
Other Views on top of a SurfaceView do work, because the framework will compose the display bits of normal Views on top of the Surface. It cannot do that with another VideoView (i.e. a SurfaceView) because there is nothing to compose.
<VideoView android:id="#+id/videoView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<VideoView android:id="#+id/videoView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
when videoView2 starts playing setvisibilty of videoView1 invisible.
then you can make it visible when you need.
Use Thread to control both video
I don't know if this is helpful at the moment, but I managed to get something similar to what you want...
I needed to nest a VideoView on top of a SurfaceView; as long as they don't overlap 100% it can work. (what i mean is, my surfaceview is the whole screen and videoview is just a small portion of the screen)
The thing is - since you can't compose SurfaceViews, the first one to grab the pixels is the one that will be shown. Intuitiveness will drive you to Z-order your prioritized view AFTER the less-important one in the XML - but as I've said previously, the first one to grab the pixels stays, so make sure you define the smaller view FIRST, and then overlay it with the bigger one.
This will result in such behaviour that the smaller (in my case preview view) acquires the said X * Y pixels, and then the 'background' surfaceview (which is supposed to be on top of it according to the XML) takes up the rest and ignores the smaller surface.
I'm not too sure about handling events from those two though as I only have to play streams in those two views and not react to any kind of clicks/events generated by those two components, but it might be expected that if you followed this route - the bigger view will intercept all clicks made in the smaller view area (because it's on top according to the XML) so maybe you have to programatically move it on top as well upon creation.
Hope it helps.
EDIT:
Although... it like it just works once. It's a work in progress really. Upon returning from any activity, there's nothing i can do to prevent the bigger view claiming everything :/
you can add videoview a on top videoview b,like this,
parentview.removeview(a);
parentview.removviewe(b);
parentview.addview(a);
parentview.addview(b);
parentview.invalidate();
Ti's work for me. I hope it can helps.