Strange shadow behavior during `alpha` animation - android

Have recycler with CardView items. When screen open - I start alpha animation on recycler :
recyclerView.animate().alpha(1f).setStartDelay(300).start()
Recycler item:
<android.support.v7.widget.CardView
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="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="6dp"
app:cardCornerRadius="10dp"
app:cardElevation="4dp">
...
</android.support.v7.widget.CardView>
Problem that while this animation running the shadow of CardView directed to the up but when animation ends shadow change direction to the bottom (as normal)
Problem was found only on Android 9.
P.S. sorry for my english)

I have found a partial fix,
If you add android:layerType="hardware" to the parent view the shadow no longer flips direction.
The down side is the shadow permanently points in the wrong direction.

Found a workaround.
Make sure the alpha-animation targets on CardView itself instead of its parent and its parent's alpha must be 1F.
This work in my case.
Hope it can help you too.

Related

Linear Layout Overlapping Navigation Bar

I can not figure out for the life of me why and how to stop the Linear Layout from overlapping the navigation bar. I am familiar with Android Studio, just not version 2+.
This problem was never a thing and I have tried multiple searches and attempts to fix this. (Screenshot below).
Put this in your LinearLayout code in the content_main.xml file.
android:layout_width="match_parent"
android:layout_height="match_parent"
In your LinearLayout set padding top 50dp
android:paddingTop="50dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
You can change margin values depending on layout position.

Exclude certain elements from being animated in android layout transitions

I have a question regarding the android layout transition framework. In particular i want to achieve an effect that a certain part of an layout slides down or up depending on the visibility of another view(s).
Imagine the following layout. (And please overlook the nested LinearLayouts here ;) )
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/changingView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<View
android:id="#+id/changingView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
<LinearLayout
android:id="#+id/movingView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="false"/>
</LinearLayout>
Now what i want to achieve is that when changingView1 and changingView2 change their visibility that movingView slides up or down.
By enabling the LayoutTransition.CHANGING for the parent layout the sliding part works fine so. But this has the side effect that the movingView will also be animated when there are being items added or removed because this layout changes its bounds. And here lies my problem because this results in a very strange looking animation.
So back to my question. Is there a way to keep the sliding animation without animating layout bound changes on the movingView?
Disabling layoutTransitions on the movingView obviously does not help because this only effects the animations of the child views. I also tried playing around with enabling and disabling different LayoutTransitions on the parent layout but so far without the desired effect.
If i can add more details please let me know otherwise i hope someone can help me out.
Thanks in advance!
I know it's late but hope it can help someone. Since android:animateLayoutChanges is the property of the direct parent, you can wrap your View/Layout in a FrameLayout (or some other ViewGroup) and set android:animateLayoutChanges="false" on the new parent.
To avoid unwanted animations you can remove the animate layout changes by code when needed, something like this:
//removing the animate layout changes to prevent the default animation for the newly added items
parentLayout.setLayoutTransition(null);
/* do some logic to add the new views */
//add the animate layout changes back so the over changes will be still animated
new Handler().post(() -> {parentLayout.setLayoutTransition(new LayoutTransition());});

Material ripple effect hidden by other view in layout

I added a ripple effect on a ImageButton, however it is hidden by an ImageView used as a background for the parent view RelativeLayout.
Here's the layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="172dp"
android:orientation="vertical"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="#+id/drawerBackgroundImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/drawer_background"/>
[...]
<ImageButton
android:id="#+id/drawerLogoutButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignBottom="#id/drawerEmailTextView"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
style="#style/FlatButtonStyle"
android:scaleType="centerInside"
android:src="#drawable/ic_logout_white_24dp"/>
</RelativeLayout>
(there's a bunch of other views but they're irrelevant here)
I'm using an ImageView as the background for the RelativeLayout as I need to set a specific scaleType for the image, so I can't use the basic android:background property.
The ripple effect is hidden as it doesn't have a mask layer (I want it to extend out of the button's bounds) and thus uses the ImageButton's parent view to be displayed. The effect is perfectly visible if I remove the ImageView.
Is there a way to get the ripple effect to be shown above the problematic ImageView?
I had exactly the same issue and solved it using this thread: https://code.google.com/p/android/issues/detail?id=155880
Issue preview:
Before solved:
After solved:
Explanation:
"Borderless buttons draw their content on the closest background. Your button might not be having background between itself and the ImageView, so it draws underneath the ImageView."
Solution:
"Use a transparent background (android:background="#android:color/transparent") on some layout containing the button (beneath the ImageView). This will dictate what the maximum bounds of the ripple effect is."
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
<!-- Your background ImageView -->
<ImageView
android:id="#+id/drawerBackgroundImageView"
android:src="#drawable/drawer_background"
... />
<!-- ... -->
<!-- HERE, you need a container for the button with the transparent
background. Let's say you'll use a FrameLayout -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<!-- Maybe more items -->
<!-- Button with borderless ripple effect -->
<ImageButton
android:id="#+id/drawerLogoutButton"
android:background="?selectableItemBackgroundBorderless"
... />
</FrameLayout>
</FrameLayout>
Hope it helps.
I am experiencing same issue. Only solution I have found so far is not 100% okay since ripple is masked by view (its not borderless).
The solution (workaround):
surround your ImageButton with other view and set ripple to the foreground instead of the background in your layout like this:
<ImageView ... />
<FrameLayout
...
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackgroundBorderless" >
<ImageButton />
</FrameLayout>
I would be really glad if someone explain why the ripple is drawn behind the image. Also if you look at Google Photos app, in image detail they have transparent icons over image view with ripple. I would like to replicate this, but I am not able to make the ripple to be in foreground. Does anybody know how to put transparent imagebuttons over everything but still have the ripple?
EDIT final solution
here you can find exactly same question link
with great explanation what is happening. the solution is the same but on top of that it solves rectangular mask by adding
android:clipChildren="false"
android:clipToPadding="false"
to your layout. now your ripple should be borderless (it worked for me).
The layout xml could be something like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:clipChildren="false"
android:clipToPadding="false">
<ImageView ... />
<FrameLayout
...
android:clickable="true"
android:foreground="?attr/selectableItemBackgroundBorderless">
<ImageView ... />
</FrameLayout>
</FrameLayout>
I'm aware this is an old post but I did struggle with this quite a bit today hence I'm posting what I was finally able to figure out and maybe someone else might benefit from it. One key emphasis beforehand, please do always RTFM!
1) The story
I aimed to use the unbounded ripple effect on Tab Items and consequently have it spread all over the AppBarLayout area. I had applied #android:color/transparent to TabLayout as the first wrapping parent and gave AppBarLayout a background color, nevertheless the ripple was still being cut off right at the borders of TabLayout's height.
2) The moral of the story (RTFM)
So I run to the nest of Android knowledge: The Documentation, and spotted this:
?android:attr/selectableItemBackgroundBorderless for a ripple that extends beyond the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null background.
3) The course of action
Using Layout Inspector, I realized that #android:color/transparent although transparent (duh!) it actually assigns 0 as the value of the bg attribute of a View, but zero is not null hence the ripple gets bounded at the nearest parent.
4) The conclusion
With that in hand, I went and set the android:background property of my TabLayout to #null rather than transparent, and now I have a fancy little ripple spread onto the area of the AppBarLayout.
5) Outro: **ANDROID & SO FTW!
Props to everyone in this post who shed light on the matter in word. Cheers!
After wrapping ImageButton inside FrameLayout, I was getting rectangular shape on touch. Applied background with oval shape on FrameLayout and got the circular shape on touch.
Had the same issue. Used the solutions described above and worked. Managed to avoid the wrapping FrameLayout by setting foreground as ?attr/actionBarItemBackground and background as #null.
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:background="#null"
android:contentDescription="#string/app_name"
android:foreground="?attr/actionBarItemBackground"
android:padding="#dimen/small_margin"
android:src="#drawable/ic_clear_text_icon" />

Android - How to get ripple effect on GridView items?

I have implemented image gallery using GridView. The layout for the grid item:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants" >
<ImageView
android:id="#+id/media_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/thumbnail_for_image"
android:scaleType="centerCrop" />
<View
android:id="#+id/overlay_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground" />
</FrameLayout>
My goal is to get this nice material ripple effect upon touching the grid item.
Unfortunately, I couldn't manage to find pure solution for my problem.
So I came up with using this, as author says, work around - adding overlay View on top of main ImageView, and setting background to
?attr/selectableItemBackground
Putting it to ImageView's background or parent FrameLayout background didn't work.
I'm sure, there must be a better way to handle it.
android:drawSelectorOnTop="true" in GridView did the trick
If you want this ripple to be supported in pre-lollipop versions I suggest you to use ripple libraries like The ones here. I guess using ?attr/selectableItemBackground won't give you ripple on pre-L androids.

How to position a view off-screen in Android layout

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.

Categories

Resources