Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: <include> with RippleEffect & StateListAnimator

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?

like image 599
TejjD Avatar asked Jan 08 '16 09:01

TejjD


People also ask

What is Android ripple effect?

The touch feedback in Android is a must whenever the user clicks on the item or button ripple effect when clicking on the same, gives confidence to the user that the button has been clicked so that they can wait for the next interaction of the app.

What causes a ripple effect?

A ripple effect occurs when an initial disturbance to a system propagates outward to disturb an increasingly larger portion of the system, like ripples expanding across the water when an object is dropped into it.

What is RippleDrawable?

android.graphics.drawable.RippleDrawable. Drawable that shows a ripple effect in response to state changes. The anchoring position of the ripple for a given state may be specified by calling setHotspot(float, float) with the corresponding state attribute identifier.


2 Answers

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);
like image 106
Stephane Mathis Avatar answered Oct 12 '22 23:10

Stephane Mathis


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>
like image 30
blizzard Avatar answered Oct 13 '22 00:10

blizzard