Một chút về android:animateLayoutChanges

android:animateLayoutChanges là gì?

Nó là một cách "magical" để animate các thay đổi trong các ViewGroup của bạn. Cái này có từ API 11 (aka Honeycomb).


Giới thiệu:

Cùng xem qua docs, thực chất nó sử dụng một đối tượng LayoutTransition mà có thể set ở bất kỳ ViewGroup nào bằng cách sử dụng phương thức setLayoutTransition và set là true, ViewGroup được cung cấp với một đối tượng mặc định LayoutTransition như đoạn code sau: code.


Cùng thử áp dụng nào:

Giả sử chúng ta có layout sau:

code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llRoot"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:animateLayoutChanges="true"
    android:background="@android:color/holo_blue_bright"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@mipmap/ic_launcher"/>

    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="some text"
        android:textAppearance="?android:attr/textAppearanceMedium"/>

</LinearLayout>

Mình cũng set thuộc tính android:animateLayoutChanges là true. Bây giờ, nếu chúng ta muốn thay đổi text thành thứ gì đó dài hơn khi khi click lên nó:

final TextView tv = (TextView) findViewById(R.id.tvText);
tv.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    tv.setText("Some longer text");
  }
});

Kết quả của đoạn code trên (view bị giật - cứng): Mặc dù mình đã thêm thuộc tính android:animateLayoutChanges vào LinearLayout để thay đổi không kích hoạt một animation. Để sửa điều này, hãy thêm đoạn code sau:

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

Như bạn nhìn thấy, phương thức enableTransitionType đã được thêm vào trong API 16 (JellyBean). Tuy nhiên, tại thời điểm mình viết bài viết này, API 16 hiện tại đang chiếm 98,40% các thiết bị nên nó thực sự không phải là vấn đề.

Ngon (view nuột nà rồi nè): Sau đây là những gì docs chính thức nói về flag LayoutTransition.CHANGING:

Một flag biểu thị animation mà chạy trên các item mà thay đổi vì một layout thay đổi (không phải bởi vì các item được thêm vào hoặc loại bỏ khỏi container). Loại transition này mặc định không được bật; nó có thể được bật thông qua enableTransitionType(int).

Một flag khác được thêm vào cùng thời điểm LayoutTransition (API 11) và LayoutTransition.CHANGING được thêm vào cùng thời điểm enableTransitionType (API 16).

Kết bài:

Tài liệu chính thức của google cũng không đề cập đến performace đối với mỗi loại flag hoặc lưu ý khi sử dụng LayoutTransition, vì thế chúng ta có thể thừa nhận rằng sử dụng nó là an toàn 😄 Tuy nhiên, nếu có vấn đề gì xảy ra, bạn có thể cung cấp cách triển khai LayoutTransition của bạn hoặc triển khai thứ gì đó theo cách của bạn.