I have a problem with mediacontroller which is hidden behind navigation bar (soft navigation keys on ICS). At first is OK (first picture), but when is navigation bar hidden for the first time, mediacontroller is resized to fit screen (correct), but is not resized back when navigation bar appears again (second picture). Also ad is moved behind (hidden for screenshot).
If I understand documentation correct fitsSystemWindows should be responsible for resizing. But it's not working.
How can I do that? Thanks for any help.
I'm testing this on Galaxy Nexus.
XML layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/playerLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:animateLayoutChanges="true"
android:background="#color/black" >
<mynamespace.BKDVideoView
android:id="#+id/videoview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
<mynamespace.SubtitleTextView
android:id="#+id/subtitleText"
style="#style/SubtitleOverlayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="30dp"
android:gravity="center"
android:visibility="gone"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"/>
<FrameLayout
android:id="#+id/adLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"/>
<FrameLayout
android:id="#+id/videoMediaControllerHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"/>
BKDVideoView is copy from GrepCode of VideoView with some customizations. I did the same for MediaController.
In MediaController I'm calling hidding like that:
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible)
{
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
// mSystemUiHolder -> FrameLayout (playerLayout)
mSystemUiHolder.setSystemUiVisibility(newVis);
Update: In case you have the same problem please check also comment in accepted answer. For views that needs to be fullscreen use sammyboy code. Thanks to both. Sorry, that I need too much time to figure this out and couldn't give you points :(
this is systembar problem. Some devices fill_parent or match_parent entities has full screensizes and do not recognize systembar width and height.
I suggest that: programmatically give an integer value to views. (calculate system bar width and height). and remove sb's width or height (landscape or portrait mode) from screensize
and set this value to the views.
here the answer how to get screen dimensions etc.
Look at this:
http://bin-liu.blogspot.no/2012/03/how-to-hide-and-display-navigation-bar.html
public void onLayoutClicked(View v) {
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
.
Display display = getWindowManager().getDefaultDisplay();
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
int rawWidth = (Integer) mGetRawW.invoke(display);
int rawHeight = (Integer) mGetRawH.invoke(display);
Use bringToFront() for the views to be at the top
Since VideoViews are SurfaceViews, they do not have the same behavior as a normal View. You need to ensure that it remains in the background by specifying:
videoview.setZOrderMediaOverlay(false);
add android:fitsSystemWindows="false" inside your framelayout that contain the surfaceview.
and this code inside your activity
your_framelayout_here.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Related
I ran into the issue concerning a ViewPager's height not being set correctly when setting android:height="wrap_content"
Now, I've successfully applied the fix mentioned here and it is working as expected. My ViewPager is correctly assuming the height of its tallest element.
However! Each of the items inside of my viewpager contains a linearlayout, which contains 2 elements, like so: (This is my container)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_margin="#dimen/gutterSpaceHalf"
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/foo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
This gives me in effect a layout that kind-of looks like this:
And what I'm trying to illustrate here is that, on the second page, LinearLayout foo will have a different height from the first page. This is expected.
But the problem comes in when I want to align the button on each page to the bottom! This is of course an issue as the bottom of foo on page one will not be the same as the bottom of foo on page two.
The standard solution, in my mind, would be to set the height of foo to match_parent. However, if I do this, the whole page becomes the height of my imageview, as the applied fix mentioned above can not calculate each child's height correctly anymore.
So, bearing in mind that my entire goal is to have equal-height pages, with dynamic content (the text), while keeping the buttons aligned to the bottom of the page, what solution would you suggest here?
Things I've tried include jiggering the height settings on layouts up the tree, and setting the height of each view to the measured height of its container upon being added in my ViewPagerAdapter, but nothing seems to be working how I want it to.
Any suggestions would be highly appreciated. Please comment if I've missed something or you'd like to see more information.
IVE DONE IT YES
All I had to do was add a view with weight=1 above my button, and give my button a static height. Now the button lines up to the bottom correctly on each page, due to the added view expanding to fill remaining size.
I also had to add +1 to the height as defined in the "hacky" solution I mentioned above, else the view I added would push items out of the largest page's layout, like so:
if (height != 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + 1 /* This is a heuristic solution */, MeasureSpec.EXACTLY);
}
YESSSSSS
(layout changes):
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View <!-- ADDED -->
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="#dimen/buttonHeight"/>
I was trying to implement YouTubePlayerView in View Pager whose parent view have a fixed height. When i click full screen/exit mode in YouTube player it's adjusting only with respect to view pager's parent height, which i guess is an obvious behavior.
<RelativeLayout
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="250dp">
<android.support.v4.view.ViewPager
android:id="#+id/productImageSlider"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true" />
<me.relex.circleindicator.CircleIndicator
android:id="#+id/indicator"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Now, as new in android, i want to know, if re-parenting the ViewPager on entering full screen mode is a good option to make it work or do i have other choices?
The simple solution is to set your views to match parent when you want to go fullscreen.
relativeLayout.setLayoutParams(
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
If when you exit fullscreen you want to go back the previous height and width, store the values somewhere and set them in the same way when the app exits fullscreen.
Having a layout which has horizontally side by side A and B parts when in landscape mode. Let's say A take 1/3 of the screen and B take other 2/3.
When rotate what is wanted is that the A keeps its original width but is changed to overlay on top of the B and B changes to have width of full screen underneath the A.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:id="#+id/left_part"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.3" />
<FrameLayout
android:id="#+id/right_part"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.7" />
</LinearLayout>
The part A, and B are holders for different fragments, which has it's adapetr with cursor etc. and could have a few stacked up in backstack. So when rotate would prefer to not re start the activity so that the context is maintained, but just some how to rearrange the layout dynamically.
Not sure if it is doable. Any suggestion?
Thanks!
Handling the Configuration Change Yourself
Your activity should be using saved instance state to persist the data from the old layout and restore it into the new layout.
It's theoretically possible to define a single layout that has sub groups from the different orientations, populate them both, then show / hide those as the rotation occurs using the method mentioned above for handling it yourself, but you are better off sticking Android's stock mechanism to handle this.
seems it should work with dynamically changing the layout, tried following shows the expected behavior.
Please comment if seeing any issue with this approach or having better solution. Thanks!
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:id="#+id/right_pane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="false"
android:layout_toRightOf="#+id/left_part" />
<FrameLayout
android:id="#+id/left_part"
android:layout_width="#dimen/left_part_width"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
void doChangeMode() {
RelativeLayout.LayoutParams leftLp = (RelativeLayout.LayoutParams) leftPart.getLayoutParams();
RelativeLayout.LayoutParams rightLp = (RelativeLayout.LayoutParams) rightPart.getLayoutParams();
if (mode == mode_side_by_side) {
mode = mode_overlap;
rightLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
} else {
mode = mode_side_by_side;
rightLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
//api 17 above
//rightLp.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
}
Handler delayHandler = new Handler();
delayHandler.post(new Runnable() {
#Override
public void run() {
rootView.requestLayout();
}
});
}
I'm using the Scene/Transition system introduced in 4.4 to simply move an image view from the left to the center of the screen. So the layout for my first scene requires the image to be off screen. I tried android:layout_marginRight but that no effect. What is the correct way to do this?
Use the property translationX or translationY with a negative value. This property sets the horizontal/vertical location of this view relative to its left/top position. You will not see the view off screen in the preview. Run your app and the view must be hidden.
Example:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:layout_margin="16dp"
android:translationX="-72dp"/>
</FrameLayout>
And then in the activity or fragment simply invoke the animate() function.
FloatingActionButton button = (FloatingActionButton)findViewById(R.id.button);
button.animate().translationX(0);
Was thinking one could make the image be to the right of something that is already at the right side, that should keep it off screen. Also, potentially just make it "gone" and then on transtion make it appear.
I have a ViewPager:
<android.support.v4.view.ViewPager android:id="#+id/ft_graph_pager"
android:layout_width="match_parent"
android:layout_height="#dimen/bar_graph_pager_height"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/ft_rsvp_graph_indicator"/>
Which is a child of a RelativeLayout. Behind this ViewPager is a 9patch image representing the lines of a graph.
The content of the ViewPager should line up with the 9patch graph lines, but I can't just make them the same height and call it a day because the ViewPager contents have a caption which should be positioned below the graph lines.
With the XML above, this is what it looks like:
I'm super close. As you can see, if I can just get the ViewPager's contents (the bar graph items and San Diego below) to shift down slightly I'm in business.
The first thing I tried to do is set layout_marginBottom="-6dp" which did nothing.
Then I tried to set paddingBottom="-6dp" which also did nothing.
Setting paddingTop="6dp" doesn't do anything either, but setting the bottom padding to a positive number DOES have an affect, even though it is completely unhelpful for me.
The RelativeLayout parent for this Pager and 9patch contains another view as well, one which is larger than both and hinges on the 9patch being perfectly vertically centered, so I can't make the 9patch move instead.
The full contents of the RelativeLayout are below:
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="#+id/ft_bar_graph_indicator"
android:layout_width="#dimen/bar_graph_indicator_width"
android:layout_height="#dimen/bar_graph_indicator_height"
android:orientation="vertical">
<!--TODO fill-->
</LinearLayout>
<View android:layout_width="match_parent"
android:layout_height="#dimen/bar_graph_height"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/ft_bar_graph_indicator"
android:background="#drawable/graph_lines"/>
<android.support.v4.view.ViewPager android:id="#+id/ft_graph_pager"
android:layout_width="match_parent"
android:layout_height="#dimen/bar_graph_pager_height"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/ft_rsvp_graph_indicator"/>
</RelativeLayout>
Any ideas?
Well, I was unable to figure out how to do this via XML, so if someone is able to do that go ahead and post it and I will make that the official answer.
However I was able to come up with a work around in Java. When I declared my ViewPager in my Activity, I just added this:
Display display = mActivity.getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
ViewHelper.setTranslationY(mGraphPager, 5 * metrics.density);
5 being the dp I ended up shifting it down. ViewHelper is part of the NineOldAndroids library, which helps simulate methods from the View class added in API 11+