Day 23 - ListView Animation
สวัสดีครับ บทความนี้เป็นบทความที่ 23 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ Learn 30 Android Libraries in 30 days
สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ
- Day 1 : AndroidStaggered Grid
- Day 2 : Paralloid
- Day 3 : Retrofit
- Day 4 : SwipeRefreshLayout
- Day 5 : Android GraphView
- Day 6 : Holo Color Picker
- Day 7 : Android Async Http
- Day 8 : Crashlytics
- Day 9 : Butter Knife
- Day 10 : Android Annotations
- Day 11 : DateTimePicker
- Day 12 : Circular Progress Button
- Day 13 : ViewPager
- Day 14 : ViewPagerIndicator
- Day 15 : FadingActionBar
- Day 16 : AutofitTextView
- Day 17 : SwipeListView
- Day 18 : ShowcaseView
- Day 19 : GreenDAO
- Day 20 : AndroidViewAnimation
- Day 21 : ActiveAndroid
- Day 22 : Twitter4J
- Day 23 : ListViewAnimations
- Day 24 : AndEngine
- Day 25 : EazeGraph
- Day 26 : Cardslib
- Day 27 : AdapterKit
- Day 28 : WeatherLib
- Day 29 : FlatUI
- Day 30 : Android Firebase
สำหรับวันนี้ขอนำเสนอเรื่อง ListViewAnimations ตัวนี้เป็น Library ที่เอาไว้เพิ่มลูกเล่น animation ให้กับ ListView เวลาที่เลือน scroll ครับ ไม่ใช่เฉพาะ ListView เท่านั้น สามารถใช้กับ GridView ก็ได้ animation ก็มีด้วยกันหลายอย่างเช่น
- Alpha ค่อยๆ สว่าง
- SwingRightIn - ไอเท็มจะวิ่งมาจากทางขวาของหน้าจอ
- SwingLeftIn - ไอเท้มจะวิ่งมาจากด้านซ้ายของหน้าจอ
- SwingBottomIn - ไอเท็มจะวิ่งขึ้นมาจากด้านล่าง
- ScaleIn
แล้วนอกจาก Animation แล้ว ยังมี Swipe-To-Dismiss ซึ่งเป็นการลบ item เมื่อทำการ swipe คล้ายๆกับ Library Day 17 : SwipeListView
Installation
ขั้นตอนการติดตั้ง เปิดไฟล์ build.gradle
ขึ้นมา แล้วเพิ่ม dependencies ลงไปดังนี้
dependencies {
compile 'com.nhaarman.listviewanimations:library:2.6.0'
}
กด Sync Gradle เป็นอันเรียบร้อย
Usage
มาถึงขั้นตอนวิธีการใช้งานตัว ListViewAnimations กันเลยครับ จะมีคลาส Adapter มาให้เราเลือกใช้งานดังนี้ครับ
- AlphaInAnimationAdapter
- ScaleInAnimationAdapter
- SwingBottomInAnimationAdapter
- SwingLeftInAnimationAdapter
- SwingRightInAnimationAdapte
เอฟเฟคก็จะแตกต่างกันไป ตามที่เกริ่นไว้นะครับ
ส่วนการ implement Adapter เหล่านี้ ทำยังไง?
[1] โดยปกติแล้ว เวลาเราสร้าง ListView หรือว่า GridView เราจะมี Adapter ของเราด้วยใช่มั้ยครับ เช่น ArrayAdapter
หรือ CustomAdapter
ก็แล้วแต่ จากนั้น เราจะใช้ Adapter ของเราเนี่ยแหละครับ เป็น argument ส่งไปให้กับ AnimationAdapter() ของ ListViewAnimations แต่ละอัน เช่น SwingBottomInAnimationAdapter
SwingBottomInAnimationAdapter swingAdapter = new SwingBottomInAnimationAdapter(myAdapter);
[2] เซต ListView ให้กับ SwingBottomInAnimationAdapter
เพื่อบอกให้รู้ว่าจะทำการ animation ListView ตัวนี้นะ
ListView listView = (ListView) findViewById(R.id.list_view);
swingAdapter.setAbsListView(listView);
[3] ให้ ListView ทำการ setAdapter()
โดยใช้ SwingBottomInAnimationAdapter
แทน Adapter ของเราเอง
listView.setAdapter(swingAdapter);
หลักการก็มีคร่าวๆแค่นี้ครับ สำหรับ Animation อื่นๆ เช่นพวก ScaleIn, SwingRightIn ก็แค่เปลี่ยนคลาส ส่วนวิธีการและ argument ต่างๆ เหมือนกันทุกอย่างครับ มาลองสร้างโปรเจ็คดูเลยดีกว่า
Create Project
สำหรับโปรเจ็คนี้ จะใช้แค่ไฟล์ ListViewAnimationActivity.java
และไฟล์เลเอาท์ชื่อ activity_listview_animation.xml
2 ไฟล์เท่านั้นครับ สำหรับไฟล์เลเอาท์ แค่มี ListView เท่านั้นครับ
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
ส่วนไฟล์จาวา ก็มีดังนี้
package com.devahoy.learn30androidlibraries.day23;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.devahoy.learn30androidlibraries.R;
import java.util.ArrayList;
public class ListViewAnimationsActivity extends ActionBarActivity {
private ArrayList<String> mDataset = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.day23_activity_listview_animation);
ListView listView = (ListView) findViewById(R.id.list_view);
for (int i = 1; i < 100; i++) {
mDataset.add("Lorem ipsum quis leo pharetra item #" + i);
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mDataset);
listView.setAdapter(adapter);
}
}
จากโค๊ดด้านบน โดยปกติเราจะสร้าง ListView โดยใช้ ArrayAdapter แบบธรรมดา ได้ด้วยโค๊ดแค่นี้ใช่มั้ยครับ ลองทดสอบรันดู จะเห็นว่ามี ListView แต่ไม่มี animation อะไรเลยทั้งสิ้น
หากว่าต้องการเพิ่ม Animation ก็แค่เพิ่มนี้ลงไป
SwingBottomInAnimationAdapter swingBottomInAdapter = new SwingBottomInAnimationAdapter(adapter);
swingBottomInAdapter.setAbsListView(listView);
adapter
ก็คือ ArrayAdapter
ของเรา และ setAbsListView(listView)
ก็คือ ListView ของเราครับ
จากนั้นสุดท้าย ก็เปลี่ยนจาก
listView.setAdapter(adapter);
เป็น
listView.setAdapter(swingBottomInAdapter);
เท่านี้ก็เรียบร้อย
package com.devahoy.learn30androidlibraries.day23;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.devahoy.learn30androidlibraries.R;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingBottomInAnimationAdapter;
import java.util.ArrayList;
public class ListViewAnimationsActivity extends ActionBarActivity {
private ArrayList<String> mDataset = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.day23_activity_listview_animation);
ListView listView = (ListView) findViewById(R.id.list_view);
for (int i = 1; i < 100; i++) {
mDataset.add("Lorem ipsum quis leo pharetra item #" + i);
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mDataset);
SwingBottomInAnimationAdapter swingBottomInAdapter =
new SwingBottomInAnimationAdapter(adapter);
swingBottomInAdapter.setAbsListView(listView);
listView.setAdapter(swingBottomInAdapter);
}
}
ทดลองรันดูผลลัพธ์กันเองนะครับ ผมไม่ได้บันทึกแบบเคลื่อนไหวไว้ (ทำไม่เป็น)
ส่วนหากต้องการให้มันเป็น Animation อื่นๆ ก็ทำได้ลักษณะเดียวกัน เช่น
ScaleInAnimationAdapter
ScaleInAnimationAdapter scaleInAdapter = new ScaleInAnimationAdapter(adapter);
scaleInAdapter.setAbsListView(listView);
listView.setAdapter(scaleInAdapter);
SwingLeftInAnimationAdapter
SwingLeftInAnimationAdapter swingLeftInAdatper = new SwingLeftInAnimationAdapter(adapter);
swingLeftInAdatper.setAbsListView(listView);
listView.setAdapter(swingLeftInAdatper);
Swipe to Dismiss
ListViewAnimations มันยังสามารถทำ Swipe to Dismiss ได้ด้วยเช่นกันครับ ตัวอย่างนี้ผมจะให้มันลบข้อมูลไอเท็มในลิสต์ออกไปเมื่อเราทำการ swipe ครับ การใช้งานก็ไม่ยากเลย เพียงแค่ใช้ swingLeftInAdatper
ดังนี้ครับ
SwipeDismissAdapter swipeDismissAdapter = new SwipeDismissAdapter(adapter, new OnDismissCallback() {
@Override
public void onDismiss(AbsListView listView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.remove(mDataset.get(position));
}
}
});
โดยสร้าง SwipeDismissAdapter
จาก adapter ของเรา และอีก parameter คือ OnDismissCallback()
และ override เมธอด onDismiss()
เมื่อมีการ swipe จะให้ทำการลบข้อมูลใน adapter ออกครับ
่ต่อมา ก็ setAbsListView()
เหมือนๆกับ AnimationAdapter
swipeDismissAdapter.setAbsListView(listView);
สุดท้าย ก็ให้ ListView ของเรา setAdatper()
ด้วยไอ้เจ้า SwipeDismissAdapter ที่สร้างมาใหม่
listView.setAdapter(swipeDismissAdapter);
ทดสอบ รัน แล้วลอง swipe ไอเท็มดูครับ จะเห็นว่าข้อมูลจะหายออกไปจากลิสท์แล้ว สุดท้าย ไฟล์ทั้งหมด มีแค่นี้แหละ
package com.devahoy.learn30androidlibraries.day23;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.devahoy.learn30androidlibraries.R;
import com.nhaarman.listviewanimations.itemmanipulation.OnDismissCallback;
import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.ScaleInAnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingBottomInAnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingLeftInAnimationAdapter;
import java.util.ArrayList;
public class ListViewAnimationsActivity extends ActionBarActivity {
private ArrayList<String> mDataset = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.day23_activity_listview_animation);
ListView listView = (ListView) findViewById(R.id.list_view);
for (int i = 1; i < 100; i++) {
mDataset.add("Lorem ipsum quis leo pharetra item #" + i);
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mDataset);
SwingBottomInAnimationAdapter swingBottomInAdapter =
new SwingBottomInAnimationAdapter(adapter);
swingBottomInAdapter.setAbsListView(listView);
ScaleInAnimationAdapter scaleInAdapter = new ScaleInAnimationAdapter(adapter);
scaleInAdapter.setAbsListView(listView);
SwingLeftInAnimationAdapter swingLeftInAdapter = new SwingLeftInAnimationAdapter(adapter);
swingLeftInAdapter.setAbsListView(listView);
SwipeDismissAdapter swipeDismissAdapter = new SwipeDismissAdapter(adapter, new OnDismissCallback() {
@Override
public void onDismiss(AbsListView listView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.remove(mDataset.get(position));
}
}
});
swipeDismissAdapter.setAbsListView(listView);
listView.setAdapter(swipeDismissAdapter);
}
}
สรุป
บทความนี้ทำเพียงแค่ ListView เท่านั้นครับ จริงๆแล้วถ้าเอาไปทำกับ GridView หรือว่า ListView ที่เป็นแบบ Custom จะสวยกว่านี้อีกครับ แต่เนื่องจากโฟกัสที่ตัว ListViewAnimations ฉะนั้นก็เลยทำแค่นี้ มีประโยชน์มากครับ ทำให้แอพพลิเคชันของเรามีชีวิตชีวาขึ้น เวลาเรา scroll เลื่อนลงมาอ่านข้อมูล ถ้ามันมี animation มันก็จะดูน่าสนใจขึ้น ดีกว่าแข็งๆทื่อๆ ใช่มั้ยครับ?
จริงๆแล้ว ListViewAnimations มันยังมีอะไรหลายๆอย่างอีกเยอะครับ ที่ไม่ได้พูดถึงในบทความนี้ ก็ลองไปอ่านเพิ่มเติมกันดูนะครับ
Happy Coding :D
Reference
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit