8

У меня есть CardView со следующими видами:ListView расширить анимации для элементов работает только после второго щелчка

- RelativeLayout (view_1) 
    - TextView 
    - TextView 

- RelativeLayout (view_2) 
    - ImageView 
    - ImageView 

Когда я открываю мой ListView view_2 установлен в Visible.GONE, так что вы не можете видеть это. Теперь я использовал ExpandAnimation от this blog. Здесь у вас есть код:

/** 
* 
*/ 
public class ExpandAnimation extends Animation { 
    /** 
    * 
    */ 
    private AnimationCallback callback = null; 
    /** 
    * 
    */ 
    private View viewToAnimate = null; 
    /** 
    * 
    */ 
    private RelativeLayout.LayoutParams viewToAnimateLayoutParams = null; 
    /** 
    * 
    */ 
    private int marginStart = 0; 
    /** 
    * 
    */ 
    private int marginEnd = 0; 
    /** 
    * 
    */ 
    private boolean isVisibleAfter = false; 
    /** 
    * 
    */ 
    private boolean isEndedAlready = false; 

    /** 
    * 
    * @param callback 
    * @param view 
    * @param duration 
    */ 
    public ExpandAnimation(AnimationCallback callback, View view, int duration) { 
     this.setDuration(duration); 

     this.callback = callback; 

     this.viewToAnimate = view; 
     this.viewToAnimateLayoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); 

     this.isVisibleAfter = (view.getVisibility() == View.VISIBLE); 

     this.marginStart = this.viewToAnimateLayoutParams.bottomMargin; 
     this.marginEnd = (this.marginStart == 0 ? (0 - view.getHeight()) : 0); 

     view.setVisibility(View.VISIBLE); 
    } 

    /** 
    * 
    * @param interpolatedTime 
    * @param transformation 
    */ 
    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation transformation) { 
     super.applyTransformation(interpolatedTime, transformation); 

     if (interpolatedTime < 1.0f) { 
      this.viewToAnimateLayoutParams.bottomMargin = this.marginStart + (int) ((this.marginEnd - this.marginStart) * interpolatedTime); 
      this.viewToAnimate.requestLayout(); 
     } else if (!this.isEndedAlready) { 
      this.viewToAnimateLayoutParams.bottomMargin = this.marginEnd; 
      this.viewToAnimate.requestLayout(); 

      if (this.isVisibleAfter) { 
       this.viewToAnimate.setVisibility(View.GONE); 
      } 

      this.isEndedAlready = true; 

      this.callback.onAnimationCompleted(-1); 
     } 
    } 
} 

я использую его в мой AdapterView:

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, AnimationCallback { 
    private TextView textViewValue = null; 
    private TextView textViewTime = null; 
    private RelativeLayout relativeLayoutExpand = null; 
    private ImageView imageViewMood = null; 
    private ImageView imageViewMeal = null; 

    public ViewHolder(View itemView) { 
     super(itemView); 

     this.textViewValue = (TextView) itemView.findViewById(R.id.textview_value); 
     this.textViewTime = (TextView) itemView.findViewById(R.id.textview_time); 
     this.relativeLayoutExpand = (RelativeLayout) itemView.findViewById(R.id.list_row_expand); 
     this.imageViewMood = (ImageView) itemView.findViewById(R.id.imageview_mood); 
     this.imageViewMeal = (ImageView) itemView.findViewById(R.id.imageview_meal); 

     itemView.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) { 
     this.animate(this.relativeLayoutExpand); 
    } 

    public void animate(final View view) { 
     ExpandAnimation expand = new ExpandAnimation(this, view, 500); 

     view.startAnimation(expand); 
    } 

    public void onAnimationCompleted(int position) { 
    } 
} 

У меня только одна проблема сейчас: Когда я развернуть элемент в моем списке первый раз, когда он появляется мгновенно, без анимации и после этого закрытие и открытие работают плавно с анимацией.

Кто-нибудь знает, почему первое открытие происходит без анимации, но каждый клик после этого запускает правильную анимацию?

Мне также нужна анимация для первого щелчка.

EDIT

Это потому, что изначально моя видимость взглядов GONE и поэтому высота неизвестна? Если да: как я могу это решить?

EDIT 2

Нет, мой файл разметки XML не установлен вид на GONE:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:layout_marginBottom="10dp"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <RelativeLayout 
      android:id="@+id/datatransfer_measure_list_row_data" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:paddingEnd="10dp" 
      android:paddingStart="10dp" 
      android:paddingTop="10dp"> 

      <TextView 
       android:id="@+id/datatransfer_measure_list_row_textview_value" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_alignParentStart="true" 
       android:lines="1" 
       android:maxLines="1" 
       android:singleLine="true" 
       android:text="@string/text_value" 
       android:textColor="@color/textcolorprimary" 
       android:textSize="30sp" /> 

      <TextView 
       android:id="@+id/datatransfer_measure_list_row_textview_time" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@+id/datatransfer_measure_list_row_textview_value" 
       android:layout_gravity="center" 
       android:layout_marginBottom="10dp" 
       android:gravity="start" 
       android:lines="1" 
       android:maxLines="1" 
       android:singleLine="true" 
       android:textColor="@color/textcolorprimary" 
       android:textSize="14sp" /> 

      <ImageView 
       android:id="@+id/datatransfer_measure_list_row_imageview_expand" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentEnd="true" 
       android:layout_alignParentTop="true" 
       android:contentDescription="@string/text_description" 
       android:scaleType="fitCenter" 
       android:src="@drawable/ic_expand_more_black_24dp" /> 
     </RelativeLayout> 

     <RelativeLayout 
      android:id="@+id/datatransfer_measure_list_row_expand" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/datatransfer_measure_list_row_data" 
      android:background="@color/primaryColor" 
      android:paddingBottom="10dp" 
      android:paddingEnd="10dp" 
      android:paddingStart="10dp" 
      android:paddingTop="10dp"> 

      <RelativeLayout 
       android:id="@+id/datatransfer_measure_list_row_mood" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="10dp"> 

       <TextView 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentStart="true" 
        android:layout_centerVertical="true" 
        android:lines="1" 
        android:maxLines="1" 
        android:singleLine="true" 
        android:text="@string/text_mood" 
        android:textColor="@color/textcolorsecundary" 
        android:textSize="30sp" /> 

       <ImageView 
        android:id="@+id/datatransfer_measure_list_row_imageview_mood" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentEnd="true" 
        android:contentDescription="@string/text_description" 
        android:scaleType="fitCenter" /> 
      </RelativeLayout> 

      <ImageView 
       android:id="@+id/datatransfer_measure_list_row_imageview_meal" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@+id/datatransfer_measure_list_row_mood" 
       android:layout_centerInParent="true" 
       android:contentDescription="@string/text_description" /> 

     </RelativeLayout> 

    </RelativeLayout> 

</android.support.v7.widget.CardView> 

Я установил View.GONE в моем ListAdapter:

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    ... 

    viewHolder.textViewTime.setText(time); 
    viewHolder.textViewValue.setText(value + " " + unitValue); 
    viewHolder.relativeLayoutExpand.setVisibility(View.GONE); // <-- HERE 

    ... 
} 

Редактировать 3

Может быть, это важно знать, что контейнер из моих cardviews является recyclerview:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/datatransfer_measure_list_textview_name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:background="@color/primaryColorDark" 
     android:gravity="center" 
     android:padding="10dp" 
     android:textColor="@color/white" 
     android:textSize="18dp" /> 

    <android.support.design.widget.CoordinatorLayout 
     android:id="@+id/datatransfer_measure_list_content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_below="@+id/datatransfer_measure_list_textview_name"> 

     <android.support.v4.widget.SwipeRefreshLayout 
      android:id="@+id/datatransfer_measure_list_swipe_refresh_layout" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/datatransfer_measure_list_row_parent" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:clipToPadding="false" 
       android:padding="10dp" 
       android:textColor="@color/textcolorprimary" /> 
     </android.support.v4.widget.SwipeRefreshLayout> 

     <android.support.design.widget.FloatingActionButton 
      android:id="@+id/datatransfer_measure_list_floating_action_button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="20dp" 
      android:layout_marginEnd="16dp" 
      android:clickable="true" 
      android:src="@drawable/ic_search_white_24dp" 
      app:backgroundTint="@color/primaryColorDark" 
      app:borderWidth="0dp" 
      app:elevation="6dp" 
      app:layout_anchor="@id/datatransfer_measure_list_row_parent" 
      app:layout_anchorGravity="bottom|right|end" 
      app:layout_behavior="de.hof.ime_dc.idia_move.views.buttons.ScrollFABBehaviour" 
      app:rippleColor="@color/accentColor" /> 

    </android.support.design.widget.CoordinatorLayout> 
</RelativeLayout> 

мне действительно нужно решение для этого. Это нарушает многие необходимые функции.

Edit 4

Я добавил некоторые LOG-выходы:

=============================== EXPAND ========================================= 

08-02 12:27:22.471 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:22.471 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:22.471 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:22.472 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

============================== COLLAPSE ======================================== 

08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginEnd: -156 
08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 8 (GONE) 

=============================== EXPAND ========================================= 

08-02 12:27:56.007 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginStart: -156 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:56.008 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

============================== COLLAPSE ======================================== 

08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginEnd: -156 
08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 8 (GONE) 

=============================== EXPAND ========================================= 

08-02 12:27:56.007 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginStart: -156 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:56.008 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

Как вы можете видеть, что первый marginStart из расширения 0, но это должно быть -156.

+0

Если это связано с вычислением высоты высоты, вы можете сделать его невидимым, а не ушли –

+0

Итак, как только вы нажмете его один раз, он будет работать каждый раз после этого? –

+0

Да, а также переработанные виды работают мгновенно. – Mulgard

ответ

2

Вы не показывали свой XML, но я предполагаю, что у вас есть android:visibility="gone". Если это так, вы должны удалить его из файла макета (чтобы он был виден по умолчанию). если он должен исчезнуть, позвоните по телефону setVisibility(View.GONE) после инфляции. Таким образом, вы получите тот же результат, но представление также сможет получить его размеры.

+0

Я обновил свое сообщение. Я не устанавливаю видимость в моем файле макета, я установил его в свой список. – Mulgard

2

Поскольку ваш код стоит, он считывает значения полей, как вы их инициализировали, как 0,0.

Чтобы получить поля, вам необходимо установить вид VISIBLE, так как он установлен в GONE, он будет иметь нулевые поля.

Так заказать такой код:

this.viewToAnimate = view; 

view.setVisibility(View.VISIBLE); 

this.viewToAnimateLayoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); 

// Now the margins will not be zero. 
this.marginStart = this.viewToAnimateLayoutParams.bottomMargin; 
this.marginEnd = (this.marginStart == 0 ? (0 - view.getHeight()) : 0); 

Не инициализирует эти переменные.

private int marginStart = 0; 
private int marginEnd = 0; 

или даже это:

private RelativeLayout.LayoutParams viewToAnimateLayoutParams = null; 

Вам нужно только инициализирует те, которые нуждаются в стартовое значение для вас, алгоритм. Как значения bool.

private boolean isVisibleAfter = false; 
private boolean isEndedAlready = false; 

У меня проблема с этой строки кода:

this.isVisibleAfter = (view.getVisibility() == View.VISIBLE); 

Я не понимаю, почему ваш код не показывает некоторые предупреждения или ошибки в вашем LogCat с этой линией.

(view.getVisibility() == View.VISIBLE) не возвращает значение видимости.

this.isVisibleAfter = view.getVisibility(); 
// will return the visibility of the view not a bool value. 

if(view.getVisibility() == View.VISIBLE){ 
// will run only if the visibility is set to visible. 
if(view.getVisibility() == View.INVISIBLE) 
if(view.getVisibility() == View.GONE) 

Это не логическое значение. Он может вернуть одно из трех значений.

Я предлагаю изменить его на:

if(view.getVisibility() == View.VISIBLE){ 

    this.isVisibleAfter = true; 
} 
else{ 
    this.isVisibleAfter = false; 
} 

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

Надеюсь, это поможет, дайте мне знать.

+0

Это не решило проблему. Такое же поведение, как и раньше. И btw: '(view.getVisibility() == View.VISIBLE)' return true или false. 'view.getVisibility()' и 'View.VISIBLE' allone возвращают значения int. Но если вы скажете '(1 == 2)', вы получите ложь. – Mulgard

+0

@ Мулгард сожалеет, что это не помогло. Сообщите нам, если вы решите его. И спасибо за подсказку о видимости. –

Смежные вопросы