How can I work with camera cutouts and PlayerView - android

I have a simple Fragment that has an ExoPlayer PlayerView.
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/black"
android:fitsSystemWindows="false">
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/videoView"
app:surface_type="texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:controller_layout_id="#layout/custom_player_controls" />
</androidx.appcompat.widget.LinearLayoutCompat>
This is what it looks like when I play a super wide video:
On the left you can see the space for the camera cutout. If I set the LinearLayoutCompat to have a background of some other color then it is really obvious that the LinearLayoutCompat is occupying the entire space, even where the cutout is. So why isn't the PlayerView taking that space?
I don't see any calls to set the PlayerView size, I just call setPlayer() and pass it my ExoPlayer instance.
Edit: I did another test. I put a view before the PlayerView and that view doesn't have the gap but PlayerView has a gap before that view.
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/black"
android:fitsSystemWindows="false">
<View
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="#color/amber_200"
/>
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/videoView"
app:surface_type="texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:controller_layout_id="#layout/custom_player_controls" />
</androidx.appcompat.widget.LinearLayoutCompat>
This is what it looks like:
Edit: After a bit of playing around I figured out the widths of the screen and of the PlayerView are the same. So I checked margins and didn't see a difference but I see there is a padding. No idea whether that is coming from:
Doing this fixes my issue but I'm not sure if that is a good solution:
binding.videoView.setPadding(0,0,0,0)

Add this in your layout file (xml)
android:fitsSystemWindows="false"
And this in your Themes
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>

Related

Snackbar flickers if android:animateLayoutChanges is true on root layout

It seems like a simple Snackbar message looks pretty jarring if android:animateLayoutChanges is set to true. The Snackbar will flicker repeatedly throughout the animation. Removing the android:animateLayoutChanges parameter from the layout solves this issue but now I won't get to enjoy the benefits from it. It also works if I use android:animateLayoutChanges on a child view instead of the root view.
Is this a known issue and is there a way around it?
Here is an example layout which will demonstrate the issue if a snackbar is shown.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:animateLayoutChanges="true">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#color/colorPrimary"
app:fabAlignmentMode="end"
app:fabCradleMargin="4dp"
app:fabCradleRoundedCornerRadius="16dp"
app:fabCradleVerticalOffset="4dp"
app:popupTheme="#style/ThemeOverlay.MaterialComponents.Light"
app:theme="#style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#color/colorAccent"
app:layout_anchor="#id/bottomAppBar"
app:srcCompat="#drawable/ic_add"
app:tint="#color/colorWhite" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Looks like an open bug. see here
Happened to me too, still not fixed of 30/07/2021. 😕
If applicable, the simplest workaround would be to put the part of layout that needs animating in a extra FrameLayout, for example like this:
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:theme="#style/AppTheme"
<-- Other views here, FragmentContainerView, AppBarLayout, ... -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<-- Place anything that you want animated here -->
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
If you would happen to have some other container views in the "useless" FrameLayout you may get "UselessParent" prompt by Android Studio, you can just include this ignore in the child of the added FrameLayout: tools:ignore="UselessParent".

VideoView in a HorizontalRecyclerView shows Wallpaper while swiping

When I scroll Horizontal RecyclerView while playing a video, the edges of videoView shows the wallpaper.
Screenshot of error
I tried vieoView, ExoPlayer, surfaceView. But all shows the same problem. when the videoView replaced with imageView the problem could be solved.
<hu.lacroix82.stretchtopviewlibrary.StretchTopScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/stretchTopView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="150dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/cl_root"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#color/background_main">
<VideoView
android:id="#+id/video_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
......
.......
.......
First of all, Check which theme you have used for this activity. Whether is it a transparent theme? Because you have tried multiple video playing library and the same issue is rising so I don't think this is an issue from the coding side. this must be from your activity theme so change your activity theme to some dark theme with a solid color. let me know if issue solved or not?

Forcing video to take up entire width of SImpleExoPlayerView

I'm having trouble forcing a video to be the entire width of a SimpleExoPlayerView. I've read through a couple stack overflow posts and have not been successful. The layout:
<FrameLayout
android:id="#+id/video_framelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="#+id/post_videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</FrameLayout>
I also tried using the following java code:
postVideoView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
postVideoView.getPlayer().setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
I had to manually reset the resize_mode:
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
android:id="#+id/video_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="#+id/post_videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:resize_mode="fixed_width"/>
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>

Can't make Floating Action Button "float"

First things first, I've checked that answer: How to add shadow to the FAB provided with the android support design library?
But even adding the app:borderWidth="0dp" or elevation="6dp" it didn't work. I have checked this answer: https://stackoverflow.com/a/30752754/1121139 it says as bigger my elevation, bigger is the shadow, and here goes the funny thing, at the preview screen it shows the shadow, but when runs at smartphone I got no shadow.
Here goes an screenshot from smartphone:
and here goes and screenshot from preview screen at android studio:
My layout code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="amaz1ngc0de.com.br.materialdesign.MainActivity">
<include android:id="#+id/app_bar" layout="#layout/toolbar_app_bar"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_test_fab"
android:layout_below="#id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<android.support.design.widget.FloatingActionButton
android:layout_margin="16dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:src="#drawable/ic_add_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:elevation="140dp"
app:borderWidth="0dp"
app:pressedTranslationZ="12dp"
android:clickable="true"/>
Try wrapping your layout inside a CoordinatorLayout and put the FAB at the same level, instead of a RelativeLayout, example:
<!-- main_layout.xml -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true"
tools:context=".activity.MainActivity">
<include layout="#layout/toolbar_app_bar" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_test_fab"
android:layout_below="#id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
... />
</android.support.design.widget.CoordinatorLayout>
Edit:
This widget is from the design library, you should have it added in your app's build.gradle file:
compile 'com.android.support:design:24.0.0'
OK so I have tried around a bit and it seems shadowing with elevation doesn't work as you imagined. This code gives quite a shadow:
<android.support.design.widget.FloatingActionButton
android:id="#+id/name_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="15dp"
android:src="#drawable/ic_add"
app:elevation="20dp"/>
But if I set elevation to 200, the shadow disappears. So there is only a range at which the shadow is working.
Maybe you can understand it as an object, casting a shadow onto an underlaying object. The higher the elevation, the greater is the distance between the two objects and the less shadow is cast...

How can I add a shadow to bottom sheet view?

As of now, with the official bottom sheet component from the Android design library implemented the top edge doesn't show a shadow. But for what I've seen in various mockups and in the Material Design specs, the bottom sheet include a discrete shadow of some sort.
I think the shadow would help distant the bottom sheet from the main layout, especially if there's a peek value set and/or the bottom sheet is always visible. Otherwise it just will blend together with the main layout and its items.
I've tried both ViewCompat.setElevation(bottomSheet, 5); and setting android:elevation="5dp" to the view in the XML, without success.
I know that a shadow shape doesn't have the same appearance as an elevation - but at least give it a try. The trick is to use app:layout_anchor to clip the shadow to the bottom sheet.
activity_main.xml
<android.support.design.widget.CoordinatorLayout 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">
<MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:id="#+id/shadow"
android:layout_width="match_parent"
android:layout_height="16dp"
android:background="#drawable/shape_gradient_top_shadow"
app:layout_anchor="#id/bottom_sheet" />
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="200dp"
android:clipToPadding="false"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />
</android.support.design.widget.CoordinatorLayout>
shape_gradient_top_shadow.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:endColor="#android:color/transparent"
android:startColor="#64000000"/>
</shape>
Looks like this:
EDIT
Get an even better result with a custom ShadowView:
Post from Roman Nurik on this topic: https://plus.google.com/+RomanNurik/posts/2QvHVFWrHZf
Gist of the ShadowView based on Roman Nurik's solution: https://gist.github.com/MariusBoepple/bf869e02541cd4750550e88fa07b5ddd
Then you can do the following:
<ShadowView
android:id="#+id/shadow"
android:layout_width="match_parent"
android:layout_height="16dp"
android:gravity="bottom"
app:layout_anchor="#id/bottom_sheet" />
For API Level 21 and higher, set the following in the parent view. You can also try in the rootview of the bottomsheet (I have not tried it in the root view)
android:background="#android:color/white"
android:elevation="16dp"
If no background then can use
android:outlineProvider="bounds"
For example, I have my sheet inside a nested scroll view
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:elevation="16dp"
android:outlineProvider="bounds"
>
<include layout="#layout/bottomsheet_1" />
</android.support.v4.widget.NestedScrollView>
The trick is to use a CardView as parent and set the elevation in the CardView
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:background="#fff"
android:clickable="true"
android:focusable="true"
app:behavior_hideable="true"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:layout_height="140dp"
app:cardElevation="8sp"
card_view:cardCornerRadius="0dp">
<!--The content of your Bottom sheet-->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
.
.
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
EDIT
This technique is not the best solution if you are supporting Kitkat and below. It's due to the extra margin added by the Cardview.
I think this will help you
first create bottom sheet like bellow then include in your main activity
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
android:layout_marginTop="0.5dp" // this margin depend on shadow area
android:background="set you color"
android:elevation="20dp" // chose your custom elevation
app:layout_behavior="#string/bottom_sheet_behavior">
<LinearLayout
android:layout_marginTop="1dp" // this margin depend on max elevation
android:layout_width="match_parent"
android:layout_height="200dp">
</LinearLayout>
</LinearLayout>

Categories

Resources