Tổng quan về ItemAnimator
ItemAnimator: Là thành phần hỗ trợ animation khi chúng ta add hay remove một item ra khỏi RecyclerView. Có các class chính sau:ItemAnimator: Là class đại diện, khung sườn của animation trong RecyclerView.
SimpleItemAnimator: class wrapper lại ItemAnimator.
DefaultItemAnimtor: class xử lý animtion mặc định sử dụng trong RecyclerView.
Chúng ta có thể viết lại class xử lý animation bằng cách extends lại class SimpleItemAnimator.
Để set ItemAnimator cho ReyclerView đơn giản là chúng ta sử dụng phương thức
setItemAnimator(ItemAnimator animator)
Notify Adapter xử lý Animation
Không giống như ListView khi chúng ta có thay đổi về mặt data thì phải gọi notifyDataSetChanged để render lại ListView. Thì ReyclerView có một số điểm khác như sau:Gọi notify đối với tại vị trí thay đổi bằng các phương thức:
notifyItemChanged(int): Notify item tại vị trí position nếu có thay đổi. Phương thức này cũng sử dụng nếu bạn muốn thực hiện animation khi item changed.
notifyItemInserted(int): Notify nếu bạn insert một item tại vị trí position. Phương thức này cũng được sử dụng nếu bạn muốn thực hiện animation khi add một item vào RecyclerView.
notifyItemRemoved(int): Notify khi bạn remove một item tại vị trí position. Phương thức này cũng được sử dụng nếu bạn muốn thực hiện animation khi remove một item ra khỏi RecyclerView.
notifyItemRangeChanged(int, int): Notify những item thay đổi trên một miền từ fromPosition. Phương thức này cũng được sử dụng nếu bạn muốn xử lý animation những item changed.
notifyItemRangeInserted(int, int): Notify các item được insert vào từ fromPosition. Phương thức này cũng được sử dụng nếu bạn muốn xử lý animation những item được insert.
notifyItemRangeRemoved(int, int): Notify các item remove ra khỏi RecyclerView từ fromPosition. Phương thức này cũng được sử dụng nếu bạn muốn xử lý animation những item được removed .
Ngoài ra RecyclerView cũng có phương thức notifyDataSetChanged giống như ListView. Tuy nhiên phương thức này sẽ không xảy ra animation.
Ví dụ như sau:
Khi bạn add 1 item vào Adapter
public void addItem(String item) {
mDatas.add(item);
//notify tại vị trí mà bạn add item.
notifyItemInserted(mDatas.size() - 1);
}
Hay
public void addItem(int position, String item) {
mDatas.add(position, item);
notifyItemInserted(position);
}
Remove một item
public void removeItem(int position) {
mDatas.remove(position);
notifyItemRemoved(position);
}
Hay
public void removeItem(String item) {
int index = mDatas.indexOf(item);
if (index < 0)
return;
mDatas.remove(index);
notifyItemRemoved(index);
}
Change một item
public void replaceItem(int postion, String item) {
mDatas.remove(postion);
mDatas.add(postion, item);
notifyItemChanged(postion);
}
Việc sử dụng ItemAnimator đơn giản là chúng ta:
+ set ItemAnimator cho RecyclerView thông qua phương thức setItemAnimator
+ Viết custom Adapter sử dụng những phương thức notify đã giới thiệu ở trên.
Bây giờ chúng ta cùng đi vào phần thực hành:
Tổng qua về ứng dụng như sau:
- Một button dùng để thực hiện thêm item vào adapter để thực hiện animation add.
- Khi click và item thì sẽ thực hiện animation change trên item đó.
- Khi giữ item sẽ thực hiện animation remove trên item đó.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eitguide.nguyennghia.animationreyclerview.MainActivity">
<Button
android:id="@+id/btn_add_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Item" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/btn_add_item" />
</RelativeLayout>
File MainActivity.java
package com.eitguide.nguyennghia.animationreyclerview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
;
private Button btnAddItem;
private RecyclerView rvItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAddItem = (Button) findViewById(R.id.btn_add_item);
rvItems = (RecyclerView) findViewById(R.id.rv_items);
List<String> data = new ArrayList<>();
for (int i = 0; i < 5; i++) {
data.add("item " + i);
}
final CustomAdapter adapter = new CustomAdapter(data);
rvItems.setAdapter(adapter);
rvItems.setLayoutManager(new LinearLayoutManager(this));
//set ItemAnimator for RecyclerView
rvItems.setItemAnimator(new DefaultItemAnimator());
btnAddItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
adapter.addItem("new item");
rvItems.scrollToPosition(adapter.getItemCount() - 1);
}
});
}
}
- Button btnAddItem sẽ add một item có nội dung là “new item” và Adapter.
- Phương thức scrollToPosition sẽ di chuyển đến vị trí mà chúng ta vừa add item
- Nhớ là set ItemAnimator cho RecyclerView.
package com.eitguide.nguyennghia.animationreyclerview;
import android.support.v7.widget.RecyclerView;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
/**
* Created by nguyennghia on 8/27/16.
*/
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private List<String> mDatas;
public CustomAdapter(List<String> data) {
mDatas = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater li = LayoutInflater.from(parent.getContext());
View itemView = li.inflate(R.layout.item_row, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String item = mDatas.get(position);
holder.tvItem.setText(item);
}
@Override
public int getItemCount() {
return mDatas.size();
}
public void addItem(String item) {
mDatas.add(item);
notifyItemInserted(mDatas.size() - 1);
}
public void addItem(int position, String item) {
mDatas.add(position, item);
notifyItemInserted(position);
}
public void removeItem(int position) {
mDatas.remove(position);
notifyItemRemoved(position);
}
public void removeItem(String item) {
int index = mDatas.indexOf(item);
if (index < 0)
return;
mDatas.remove(index);
notifyItemRemoved(index);
}
public void replaceItem(int postion, String item) {
mDatas.remove(postion);
mDatas.add(postion, item);
notifyItemChanged(postion);
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvItem;
public ViewHolder(final View itemView) {
super(itemView);
tvItem = (TextView) itemView.findViewById(R.id.tv_item);
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
removeItem(getAdapterPosition());
Toast.makeText(itemView.getContext(), "Removed Animation", Toast.LENGTH_SHORT).show();
return false;
}
});
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
replaceItem(getAdapterPosition(), "item changed");
Toast.makeText(itemView.getContext(), "Changed Animation", Toast.LENGTH_SHORT).show();
}
});
}
}
}
Với row của 1 item (item_row.xml) có nội dung
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="#ecf0f1">
<TextView
android:id="@+id/tv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="#2c3e50"
android:textSize="16dp" />
</FrameLayout>
Kết quả chúng ta sẽ thấy như video Demo dưới đây:
https://www.youtube.com/watch?time_continue=61&v=pxHpwFpT4Lc&feature=emb_logo
Vì chúng ta sử dụng DefaultAnimator nên Animation sẽ như sau:
- Animation Added: Thực hiện thay đổi Alpha của itemView từ 0 đến 1:
- Animation Removed: Thực hiện thay đổi giá trị Alpha của itemView từ 1 về 0.
- Animation Changed: Thực hiện Animation từ 1 về 0 và sau đó set Animation từ 0 đến 1 để thay đổi item.
Nếu bạn nào có hứng thú muốn tìm hiểu cách viết ItemAnimator có thể liên hệ mình để có thể trao đổi chi tiết hơn.
Source code ItemAnimatorReyclerView
Comments
Post a Comment