full screen video below navigation bar - android

On Android 4 and up (excluding 4.4) when an app goes full screen (with SYSTEM_UI_FLAG_HIDE_NAVIGATION), then after the first touch the navigation bar appears (with software navigation keys). This means that all my layouts are moved up and have smaller sizes. This makes an ugly jump of all the layouts. Is there a way to make the navigation bar overlay my layout instead of pushing it up?
I want to make a video player with YouTube like behavior, where the navigation bar overlays the video after the touch so the video does not move up and shrinks a bit, which is annoying. System/status bar is not a problem, just the navigation bar. Thank you.

Forget on my previously answer not working on all versions. The right approach is to find out navigation bar height and add bottom margin -navigationBarHeight. This is full working example work on all 4.1+ versions:
public static int getNavigationBarHeight(Context context) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
#SuppressLint("NewApi")
private int getRealScreenSize(boolean returnWidth) {
final DisplayMetrics metrics = new DisplayMetrics();
Display display = getActivity().getWindowManager().getDefaultDisplay();
Method mGetRawH = null, mGetRawW = null;
//Not real dimensions
display.getMetrics(metrics);
int width = metrics.heightPixels;
int height = metrics.widthPixels;
try {
// For JellyBeans and onward
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
display.getRealMetrics(metrics);
//Real dimensions
width = metrics.heightPixels;
height = metrics.widthPixels;
} else {
mGetRawH = Display.class.getMethod("getRawHeight");
mGetRawW = Display.class.getMethod("getRawWidth");
try {
width = (Integer) mGetRawW.invoke(display);
height = (Integer) mGetRawH.invoke(display);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
} catch (NoSuchMethodException e3) {
e3.printStackTrace();
}
if (returnWidth) {
return width;
} else {
return height;
}
}
Following example code need to put somewhere after surface was created:
RelativeLayout.LayoutParams lp = (LayoutParams) surfaceView.getLayoutParams();
int screenHeight = getRealScreenSize(false);
int screenWidth = getRealScreenSize(true);
int navigationBarHeight = getNavigationBarHeight(getActivity());
lp.height = (int) (screenWidth / (16d / 9d));
lp.width = screenWidth;
int k = (lp.height - screenHeight) / 2;
lp.setMargins(0, -k, 0, (-k) - navigationBarHeight);
surfaceView.setLayoutParams(lp);
Note that surface view must have parent RelativeLayout.

This works, need to put onCreate():
WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
getWindow().setAttributes(attributes);
More info you can find on link: http://www.thekirankumar.com/blog/2013/02/10/show-and-hide-android-notification-bar-without-causing-a-layout-jerk/

In below links there have written details about working with " System UI " & " Work with SYSTEM_UI_FLAG_LOW_PROFILE , SYSTEM_UI_FLAG_VISIBLE & SYSTEM_UI_FLAG_HIDE_NAVIGATION" :
http://developer.android.com/about/versions/android-4.0.html#SystemUI
https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int)
https://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION
I believe another nice question about " Hide System Bar " with some nice answers :
Hide System Bar in Tablets
Hope these will help you to get your work done.
Happy coding !!!

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions);
Those flags make system and navigation bars overlay your content

Related

Tab max width percentage screen

Hello I need set a maxwidth to my tabs, but it is not a fix size it is going to be a porcentage of screen then I supose that I have to do it programmatically, but I not have idea how can I do it. Any help? thank you
Edit: I don't know how much tabs I have to draw, I get it from a service
Finally I created a custom view for my tab and calculate and set the screen porcentage programmatically
private void setTabView(List<String> rowList) {
for (int i = 0; i < rowList.size(); i++) {
View view = LayoutInflater.from(this).inflate(R.layout.custom_tab_item, null);
TextView tv = view.findViewById(R.id.tv_tab);
tv.setText(rowList.get(i));
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
tv.setMaxWidth(((int) (width * MAX_TAB_SIZE_PORCENT)));
try {
tabLayout.getTabAt(i).setCustomView(view);
} catch (Exception e) {
Timber.tag(TAG).i(e);
}
}
}
custom_tab_item is just a TextView
hope help :)

Cutout of application by notch

My application is cut off from the top side by the notch
Is there any specific solution to overcome this problem.
I am using the emulator Pixel 3 XL API 27
image for illustrstion
What should I do any code is there to increase the height of the top bar or status bar or should I increase the height of the title bar, but the title bar is still cut off
Any suggestion or code explanation
Try below solution
It is get size of notch as per device and set margin top to view So,it's fit in all device.
#Override
protected void onCreate(Bundle savedInstanceState) {
this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
this.getWindow().setStatusBarColor(Color.TRANSPARENT);
super.onCreate(savedInstanceState);
setContentView(MainActivity.this, R.layout.activity_main);
/*------------ Check display cutout size and give top margin to toolbar -------------*/
setMarginTopAccordingDisplayCutout(context, yourTopMainView, convertDpToPixel(34), 0);
/*-----------------------------------------------------------------------------------*/
...
//your Code
}
private void setMarginTopAccordingDisplayCutout(Context context, View view, int extraTopWithoutCutout, int extraTopWithCutout) {
int statusBarHeight = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
if (statusBarHeight > convertDpToPixel(24)) {
final ViewGroup.MarginLayoutParams[] layoutParams = new ViewGroup.MarginLayoutParams[1];
layoutParams[0] = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
layoutParams[0].topMargin = statusBarHeight + extraTopWithCutout;
view.setLayoutParams(layoutParams[0]);
//topbarlp.setMargins(0, statusBarHeight, 0, 0);
//Set above layout params to your layout which was getting cut because of notch
///topbar.setLayoutParams(topbarlp)
Log.e(TAG, "onCreate statusBarHeight :: " + statusBarHeight);
} else {
final ViewGroup.MarginLayoutParams[] layoutParams = new ViewGroup.MarginLayoutParams[1];
layoutParams[0] = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
layoutParams[0].topMargin = extraTopWithoutCutout;
view.setLayoutParams(layoutParams[0]);
}
}
private int convertDpToPixel(float dp) {
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return Math.round(px);
}
I hope this can help you!
Thank You.

Ho to get s8 useable screen android?

I am noob in android. My problem about useable height of 18:9 devices.
When I try to get useable screen in these aspect-ratio my application is woking fine all android devices but when ı compile in Samsung Galaxy s8 it is not working.
I am trying to get useable screen of devices.
I have already tried method which in these links
https://stackoverflow.com/questions/43628047/how-to-support-189-aspect-ratio-in-android-apps
https://android-developers.googleblog.com/2017/03/update-your-app-to-take-advantage-of.html
And I use dynamically
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels ;
And I tried
private int getSoftButtonsBarHeight() {
// getRealMetrics is only available with API 17 and +
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}
And when I try to set params MATCH_PARENT height it is working good. But I need to find useable height pixel to desing my other views proportionally .
Actually these code DisplayMetrics metrics = this.getResources().getDisplayMetrics();
height = metrics.heightPixels ; working in my Activity but when I try to use it in another window which I extend from FramaLayout and add to activity it is not working.
Here is my code block
public class StudentLoginActivity extends Activity { ...
FrameLayout.LayoutParams containerParams = new ScrollView.LayoutParams(width, height-sb);
container = new FrameLayout(this);
container.setLayoutParams(containerParams);
container.setBackgroundColor(Color.rgb(248,248,248));
loginStudentView = new StudentLoginView(this);
container.addView(loginStudentView); ...
}
public class StudentLoginView extends FrameLayout { ...
FrameLayout.LayoutParams cp = new FrameLayout.LayoutParams(width, height);
setLayoutParams(cp); ...
}
But this problem related with android navigationBar height because when I show navigation bar there is no problem but if I hide navigationBar it is not resize application still working that there is a navigation bar on screen (but I hide the navigationBar).
My problem is very similar this link
android Navigation Bar hiding and persantage of usable screen overlap
You can get the useable height (even on Galaxy S8 with or without shown NavBar) with the decorview:
//Get the correct screen size even if the device has a hideable navigation bar (e.g. the Samsung Galaxy S8)
View decorView = getWindow().getDecorView(); //if you use this in a fragment, use getActivity before getWindow()
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int screenHeight = r.bottom; // =2220 on S8 with hidden NavBar and =2076 with enabled NavBar
int screenWidth = r.right; // =1080 on S8
If you have a view that is set to match the parent width and height (the whole screen), you can attach a listener to that view and then get its width and height.
View myView = findViewById(R.id.my_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight,
int oldBottom) {
// its possible that the layout is not complete in which case
// we will get all zero values for the positions, so ignore the event
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return;
}
// Do what you need to do with the height/width since they are now set
}
});
This answer was taken from here.

Moto360 addview with black bar on bottom

everyone. I try to attach full screen view to moto360. However, when it works on LG/samsung square devices. It left a black out bar on bottom, which is about same size of original black bar on bottom. Is this a bug or what? anyone ever found this happened?
Here's my code:
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
float width = metrics.widthPixels;
float height = metrics.heightPixels;
Log.d(TAG, "width: " + width + " height:" + height);
// attatch view to windows
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
wmParams.format = PixelFormat.RGBA_8888;
wmParams.flags = LayoutParams.FLAG_NOT_TOUCHABLE
| LayoutParams.FLAG_NOT_FOCUSABLE
| LayoutParams.TYPE_SYSTEM_OVERLAY;
wmParams.gravity = Gravity.TOP | Gravity.TOP;
wmParams.x = 0;
wmParams.y = 0;
wmParams.width = metrics.widthPixels;
wmParams.height = metrics.heightPixels;
wManager.addView(view, wmParams);
by the way, change metrics.widthPixels to Match_Parent is not working.
Any clue is appreciated. For now I suspect it is a bug on moto360 rom which consider the screen size as (real space - bottom bar size). So, when the view is attached, is return some black space on bottom.

adding dynamic view using WindowManager.addView

I have a code on ICS for tablets. I want to add a Imageview dynamicly to a fragment. The fragment already contains preferencelist. The code for adding the view dynamically is as follows. I am coding this drag and drop functionality. This part of the code is taken from TouchInterceptor.java file from android music app.
mWindowParams = new WindowManager.LayoutParams();
mWindowParams.gravity = Gravity.TOP ;
mWindowParams.x = 0;
mWindowParams.y = y
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mWindowParams.format = PixelFormat.TRANSLUCENT;
mWindowParams.windowAnimations = 0;
ImageView v = new ImageView(mContext);
int backGroundColor = mContext.getResources().getColor(R.color.bg_background);
v.setBackgroundColor(backGroundColor);
v.setImageBitmap(bm);
mWindowManager = (WindowManager)mContext.getSystemService("window");
mWindowManager.addView(v, mWindowParams);
I am specifying the x coordinate of windowlayout param as 0. Eventthen when the view is displayed , itstead of displaying from the leftside of the fragment(the right pane) ,the view is displayed from middle of the right pane and is spanning to the right pane . What I am doing wrong ? Whats has to be done to correct this ?
Try setting gravity to Gravity.TOP | Gravity.LEFT
I m working exatly on the same code taken from the old Google Music open souce project.
Like you I guess, I had a TouchInterceptor in a fragment. My problem was that the fragment does not take all the screen widht, it has an other fragment on its left.
I tried a lot using mWindowParams.gravity to be able to specify an absolute x,y but I couldn't find a solution. Eventually I solved it with mWindowParams.horizontalMargin.
Here is the code I came up with:
private int getAbsoluteLeft(){
ViewGroup parent;
View child = this;
int left_absolute_position = 0;
try{
while( (parent = (ViewGroup) child.getParent()) != null) {
left_absolute_position += child.getLeft();
child = parent;
}
}catch(ClassCastException e){
}
return left_absolute_position;
}
private void startDragging(Bitmap bm, int x, int y) {
stopDragging();
//build the view
Context context = getContext();
ImageView v = new ImageView(context);
//int backGroundColor = context.getResources().getColor(R.color.dragndrop_background);
//v.setBackgroundColor(backGroundColor);
//v.setBackgroundResource(R.drawable.playlist_tile_drag);
v.setPadding(0, 0, 0, 0);
v.setImageBitmap(bm);
mDragBitmap = bm;
mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//Build Params
mWindowParams = new WindowManager.LayoutParams();
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowParams.x = ( x - mDragPointX + mXOffset );
mWindowParams.y = ( y - mDragPointY + mYOffset );
DisplayMetrics metrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metrics);
mWindowParams.horizontalMargin = (float)getAbsoluteLeft() / (float)metrics.widthPixels;
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
mWindowParams.format = PixelFormat.TRANSLUCENT;
mWindowParams.windowAnimations = 0;
mWindowManager.addView(v, mWindowParams);
mDragView = v;
}
The part I added is:
DisplayMetrics metrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metrics);
mWindowParams.horizontalMargin = (float)getAbsoluteLeft() / (float)metrics.widthPixels;
This parameter mWindowParams.horizontalMargin specify the margin of the window from the specified gravity side (Gravity.Left) as a % € [0,1].
So with getAbsoluteLeft() I go up to the View tree to get the absolute distance of the list from the left side.
Dividing it by the window's width, you get percent of margin you need.

Categories

Resources