Подтвердить что ты не робот

Android: <include> с RippleEffect & StateListAnimator

У меня есть макет, который включает в себя другой макет:

<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>

Мне нужно добавить RippleEffect, а также StateListAnimator к включенному макету.

Пример:

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

И RippleEffect, и StateListAnimator работают на 100%. Я не могу изменить включенный макет. Таким образом, причина, по которой мне нужно делать эффекты либо с тегом include, либо с самим родительским макетом.

Я пробовал обе технологии, ни одна из которых не была успешной.

ОБНОВЛЕНИЕ

Если возможно, это должно быть программно недоступным.

ОБНОВЛЕНИЕ 2

Во-вторых, как бы я продолжаю держать View повышенным, как только он анимируется?

4b9b3361

Ответ 1

Вам нужно найти представление и вызвать соответствующий метод для изменения аниматора списка состояний и фона. Возможно, вам также придется вызвать setClickable в корневом представлении, в котором вы включили макет.

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);

Ответ 2

Основываясь на потоке Включает ли XML-макет Android "тег действительно работает? и LayoutInflater.java кажется, что тэг <include> поддерживает только атрибуты android:id, layout_* и android:visibility. Таким образом, ваш код для установки background и stateListAnimator не имеет эффекта.

Чтобы исправить следующую проблему с помощью @Stepane:

ваш метод позволяет эффект пульсации правильно, однако SLA не уволена. Я не вижу никакого места.

Если завышенный вид прозрачен, то высота не видна, вам нужно установить viewOutline или использовать некоторый непрозрачный цвет для просмотра, чтобы увидеть тень.

Выдержка из ViewOutlineProvider документация:

Интерфейс, с помощью которого View создает свой контур, используемый для теневого литья и отсечения.

Чтобы установить outlineProvider, вы можете использовать метод View # setOutlineProvider (ViewOutlineProvider provider) или вы можете установить через android:outlineProvider тег xml.

Обновленный код:

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>

Рез/аниматор/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>