2016-07-07 25 views
5

Tôi có một màn hình với Recyclerview và các phần tử khác bên trong LinearLayout. Vấn đề là khi tôi loại bỏ một mục của RecyclerView, animateLayoutChanges không hoạt động trong trường hợp này. Anayone có biết tại sao điều này xảy ra không ??AnimateLayoutChanges không hoạt động với 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()); 
       } 
      }); 

     } 
    } 
} 

Trả lời

5

Sau một thời gian tôi nhận được một giải pháp. Tôi đã tạo một hàm để tạo hiệu ứng cho chiều cao recyclerView.

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

gì làm việc đối với tôi là chỉ cần thêm đoạn mã sau vào onCreate:

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

nơi llRoot là bạn r LinearLayout chứa RecyclerView.

Bạn cần giữ android:animateLayoutChanges="true" trên LinearLayout của mình, nếu không nó sẽ bị treo.

Tôi tin rằng nếu bạn muốn hỗ trợ điều này bên dưới Jellybean, bạn sẽ cần giải pháp tùy chỉnh của mình.

Giải thích về giải pháp ở đây: https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec

Các vấn đề liên quan