Android: <include> with RippleEffect & StateListAnimator
Asked Answered
K

2

14

I have a layout, that includes another layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical"
          android:id="@+id/layout1">

    <include layout="@layout/my_layout"/>
</LinearLayout>

I need to add a RippleEffect as well as a StateListAnimator to the included layout.

Example:

<include layout="@layout/my_layout"
          android:stateListAnimator="@anim/lift_up"
          android:background="@drawable/ripple_effect"/>

Both the RippleEffect and StateListAnimator work 100%. I cannot alter the included layout. Thus the reason why I need to do the effects either on the include tag or the parent layout itself.

I have tried both techniques, none of which have been successful.

UPDATE

If possible, this should be down programmatically.

UPDATE 2

Secondly, how would I go about keep the View elevated, once it has animated?

Kythera answered 8/1, 2016 at 9:50 Comment(0)
S
3

You need to find the view and call the appropriate method to change the state list animator and the background. You might need to also call setClickable on the root view of you included layout.

LinearLayout layout1 = findViewById(R.id.layout1);
View root = layout1.getChildAt(0);

StateListAnimator sla = AnimatorInflater.loadStateListAnimator(context, R.anim.lift_up); 
root.setStateListAnimator(sla);
root.setBackground(R.drawable.ripple_effect);
Soupspoon answered 12/1, 2016 at 8:17 Comment(7)
This seems legit enough. I have updated the question with another aspect based on the SLA.Kythera
You edit is a different question. You should open another one with that specific problem.Soupspoon
Cool. With the current question, your method enables the ripple effect properly, however the SLA isn't fired. I cannot see any elevation taking placeKythera
Can you test with another animation ? To see if the problem is to apply the animation programmatically or if it's a problem linked to the elevation.Soupspoon
I am using the same animation on a card view else where. The elevation is working 100%Kythera
Ok, maybe try without the ripple effect as the background. I don't really know what the problem is.Soupspoon
Tried everything. It is not elevating at all.Kythera
B
2

Based on the thread Does Android XML Layout's 'include' Tag Really Work? and LayoutInflater.java it seems <include> tag only supports android:id, layout_* and android:visibility attributes. So your code to set background and stateListAnimator have no effect.

To fix the below issue with @Stepane's code :

your method enables the ripple effect properly, however the SLA isn't fired. I cannot see any elevation taking place

If the inflated view is transparent, then the elevation is not visible, you have to set viewOutline or use some non-transparent color for the view to see the shadow.

An extract from ViewOutlineProvider documentation:

Interface by which a View builds its Outline, used for shadow casting and clipping.

To set the outlineProvider you can make use of View#setOutlineProvider (ViewOutlineProvider provider) method or you can set via android:outlineProvider xml tag.

Updated Code:

LinearLayout root =(LinearLayout) findViewById(R.id.container);
StateListAnimator sla = AnimatorInflater.loadStateListAnimator(this, R.animator.lift_up);
root.setStateListAnimator(sla);
root.setClickable(true);
root.setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
root.setBackground(ContextCompat.getDrawable(this, R.drawable.ripple_effect));

ripple_effect.xml

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="?android:colorAccent"
    tools:ignore="NewApi">
  <item>
    <shape
        android:shape="rectangle">
        <solid android:color="@android:color/transparent"/>            
        <!-- Doesn't require outlineProvider
        <solid android:color="@android:color/darker_gray"/>
        -->
    </shape>
  </item>
</ripple>

res/animator/lift_up.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
      android:state_enabled="true"
      android:state_pressed="true">
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="translationZ"
        android:valueTo="48dp"/>
  </item>
  <item>
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="translationZ"
        android:valueTo="0dp"/>
  </item>
</selector>
Blakemore answered 14/1, 2016 at 22:31 Comment(5)
Thanks for the explanation, but it still isn't working. I think the issue is that include tag matches parent width, so the actual elevation isn't visible. I have tried your method in every way possible. To no availKythera
@Kythera I have tried using match_parent for height and width, everything is working fine. I have updated the post to include lift_up.xml(elevation) code for clarity, check it out. Just curious, Which device and android version are you using for the test run?Blakemore
That is the exact code I am using as well. I am testing on a Nexus 6P, running MarshmallowKythera
@Kythera I'd tried the code in the Nexus6P, it's working fine. Please share the my_layout and its related files and the java code you are using to inflate the layout and set the SLAnimators.Blakemore
My included layout is a simple imageview with a 2 textviews. And I am using the same code that you and stephane provided. I feel like there is an issue with the width. I will keep tryingKythera

© 2022 - 2024 — McMap. All rights reserved.