2016-07-07 3 views
5

Ich habe einen Bildschirm mit einem Recyclerview und anderen Elementen innerhalb von LinearLayout. Das Problem ist, wenn ich ein Element der RecyclerView entfernen, funktioniert in diesem Fall animateLayoutChanges nicht. Weiß jemand, warum das passiert?AnimateLayoutChanges funktioniert nicht mit RecyclerView

Demo

XML

<LinearLayout 
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" 
tools:context="com.example.alvaro.resizetest.MainActivity"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:animateLayoutChanges="true" 
    android:orientation="vertical"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerview" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <LinearLayout 
     android:id="@+id/test1" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorAccent" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test2" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorPrimaryDark" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test3" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorAccent" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test4" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorPrimaryDark" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


</LinearLayout> 

JAVA

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 

    Adapter adapter = new Adapter(); 

    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    recyclerView.setAdapter(adapter); 
    recyclerView.setNestedScrollingEnabled(true); 

    View.OnClickListener listener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      view.setVisibility(View.GONE); 
     } 
    }; 

    findViewById(R.id.test1).setOnClickListener(listener); 
    findViewById(R.id.test2).setOnClickListener(listener); 
    findViewById(R.id.test3).setOnClickListener(listener); 
    findViewById(R.id.test4).setOnClickListener(listener); 

} 


class Adapter extends RecyclerView.Adapter<Adapter.Holder>{ 

    int size = 3; 

    public Adapter() { 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View view = getLayoutInflater().inflate(R.layout.item, parent, false); 

     return new Holder(view); 
    } 

    @Override 
    public void onBindViewHolder(Holder holder, int position) { 

    } 

    @Override 
    public int getItemCount() { 
     return size; 
    } 

    class Holder extends RecyclerView.ViewHolder { 

     public Holder(final View itemView) { 
      super(itemView); 

      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        size --; 
        notifyItemRemoved(getAdapterPosition()); 
       } 
      }); 

     } 
    } 
} 

Antwort

5

Nach einer Weile bekam ich eine Lösung. Ich habe eine Funktion erstellt, um die RecyclerView-Höhe zu animieren.

enter image description here

JAVA

public class MainActivity extends AppCompatActivity { 

private final String TAG = MainActivity.class.getSimpleName(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 

    Adapter adapter = new Adapter(recyclerView); 

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) { 
     @Override 
     public boolean canScrollVertically() { 
      return false; 
     } 
    }; 

    recyclerView.setLayoutManager(linearLayoutManager); 
    recyclerView.setAdapter(adapter); 
    recyclerView.setNestedScrollingEnabled(true); 

    View.OnClickListener listener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      view.setVisibility(View.GONE); 
     } 
    }; 

    findViewById(R.id.test1).setOnClickListener(listener); 
    findViewById(R.id.test2).setOnClickListener(listener); 
    findViewById(R.id.test3).setOnClickListener(listener); 
    findViewById(R.id.test4).setOnClickListener(listener); 

} 


public void animateHeight(final View v, final int height) { 

    final int initialHeight = v.getMeasuredHeight(); 
    int duration = 500; 
    Interpolator interpolator = new AccelerateInterpolator(2); 

    // I have to set the same height before the animation because there is a glitch 
    // in the beginning of the animation 
    v.getLayoutParams().height = initialHeight; 
    v.requestLayout(); 

    Animation a = new Animation() { 
     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      Log.d(TAG, "InterpolatedTime: " + interpolatedTime); 
      Log.d(TAG, "Collapsing height: " + (initialHeight - (int) (height * interpolatedTime))); 
      v.getLayoutParams().height = initialHeight - (int) (height * interpolatedTime); 
      v.requestLayout(); 
     } 

     @Override 
     public boolean willChangeBounds() { 
      return true; 
     } 
    }; 

    a.setDuration(duration); 
    a.setInterpolator(interpolator); 
    v.startAnimation(a); 
} 


class Adapter extends RecyclerView.Adapter<Adapter.Holder> { 

    RecyclerView mRecyclerView; 
    int size = 3; 

    public Adapter(RecyclerView recyclerView) { 
     mRecyclerView = recyclerView; 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View view = getLayoutInflater().inflate(R.layout.item, parent, false); 

     return new Holder(view); 
    } 

    @Override 
    public void onBindViewHolder(Holder holder, int position) { 

    } 

    @Override 
    public int getItemCount() { 
     return size; 
    } 

    class Holder extends RecyclerView.ViewHolder { 

     public Holder(final View itemView) { 
      super(itemView); 

      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        size--; 
        notifyItemRemoved(getAdapterPosition()); 
        animateHeight((View) itemView.getParent(), itemView.getMeasuredHeight()); 
       } 
      }); 

     } 
    } 
} 

}

0

Was für mich gearbeitet einfach war, den folgenden Code zu onCreate:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
    ((ViewGroup) findViewById(R.id.llRoot)).getLayoutTransition() 
     .enableTransitionType(LayoutTransition.CHANGING); 
} 

wo llRoot Sie ist r LinearLayout mit RecyclerView.

Sie müssen android:animateLayoutChanges="true" auf Ihrem LinearLayout behalten, sonst stürzt es ab.

Ich glaube, wenn Sie dies unter JellyBean unterstützen möchten, würden Sie Ihre benutzerdefinierte Lösung benötigen.

Erklärung zur Lösung ist hier: https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec