Day 4 - Swipe Refresh Layout
สวัสดีครับ บทความนี้เป็นบทความที่ 4 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ 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
ส่วนวันนี้นำเสนอ Library ตัวที่สี่ ชื่อว่า SwipeRefreshLayout ครับ ตัวนี้เป็น Library
SwipeRefreshLayout คืออะไร?
SwipeRefreshLayout เป็น View ชนิดหนึ่ง ที่เอาไว้ให้ User สามารถที่จะ refresh เนื้อหาโดยการใช้การ swipe ได้ การใช้งาน SwipeRefreshLayout
ก็คล้ายๆกับการใช้งานพวก ScrollView คือจะเป็นคล้ายๆ ตัว Container คอยหุ้มพวก View อื่นๆ อีกทีนึง โดยส่วนตัวไม่แน่ใจว่า ตัว SwipeRefreshLayout
กับตัว Actionbar Pull To Refresh มันคือตัวเดียวกันหรือไม่ เหมือนกับว่าทาง Android เพิ่งจะนำมาใส่เป็น default รึเปล่า? อันนี้ใครพอทราบ รบกวนช่วยบอกด้วยนะครับ
Getting Started
เนื่องจากไม่ต้องติดตั้งอะไรเพิ่มเติม เพราะว่าตัว SwipeRefreshLayout มันอยู่ใน Support Library v4 อยู่แล้ว ถ้าหากใครไม่ได้โหลด Support Library ก็ไปโหลดมาซะ
การใช้งาน ก็ง่ายๆครับ สร้างไฟล์เลเอา์ท์ xml โดยใช้ SwipeRefreshLayout
เป็น container คอยหุ้ม View อื่่นๆ แบบนี้
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
ต่อมาที่คลาส SwipeToRefreshActivity.java
ผมทำการประกาศ ListView
, ArrayAdapter
และ SwipeRefreshLayout
แบบนี้
package com.devahoy.learn30androidlibraries.day4;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.devahoy.learn30androidlibraries.R;
import java.util.ArrayList;
import java.util.Random;
public class SwipeToRefreshActivity extends ActionBarActivity {
private SwipeRefreshLayout mSwipeRefresh;
private ListView mListView;
private ArrayAdapter<String> mSimpleAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.day4_activity_swipe_to_refresh);
mSwipeRefresh = (SwipeRefreshLayout)
findViewById(R.id.swipe_refresh_layout);
mListView = (ListView) findViewById(R.id.list_view);
}
}
การใช้งาน SwipeRefreshLayout
การใช้งาน SwipeRefreshLayout เมื่อเรา declare มันที่ไฟล์ layout และก็ทำการเชื่อมมันเข้ากับคลาสในโค๊ดแล้ว ขั้นตอนต่อมา ถ้าจะให้ตัว SwipeRefreshLayout
ทำงาน ก็ต้องใช้เมธอด setOnRefreshListener()
ให้มันครับ คล้ายๆกับการ setListernr ให้กับพวก Button หรือว่า ListView แบบนี้
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
}
});
โดยหาก user มีการ swipe หน้าจอ ตัว SwipeRefreshLayout
จะทำงานที่เมธอด onRefresh()
ฉะนั้น Logic ทุกๆอย่าง ก็ต้องทำในเมธอดนี้ เช่น เมื่อมีการ refresh ให้ไปดาวน์โหลดข้อมูลมาใหม่ จากนั้นก็ refresh ListView และโชว์ข้อมูลอันใหม่
ทดสอบลองรันดู แล้วลอง swipe ดู ปรากฎว่าทำงานได้ แต่ตัว Progress เป็นสีเทาๆ ดำๆ
แต่ว่า ListView อุตส่ามีแล้ว แต่ไม่ได้โชว์ข้อมูลอะไรเลย ก็สร้างข้อมูลให้ ListView ซะหน่อย สร้างเมธอดและตัวแปร ขึ้นมาแบบนี้ (ทำการ random และเพิ่มข้อมูลเข้าไป)
private void initSampleData() {
for (int i = 0; i < 5; i++) {
int index = random.nextInt(lorems.length);
mData.add(lorems[index]);
}
}
private String[] lorems = new String[] {
"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"Vivamus fringilla adipiscing neque, a lacinia metus pretium et",
"Donec quam justo, vehicula ut mauris vel, luctus cursus libero",
"Pellentesque ac fermentum augue, id congue tortor.",
"Proin mattis ac nibh vitae volutpat. Pellentesque commodo eros quis enim tempus",
"Fusce sagittis orci sit amet magna tempus, ut dignissim urna malesuada",
"Quisque sit amet libero volutpat velit euismod sollicitudin.",
"Interdum et malesuada fames ac ante ipsum primis in faucibus",
"Cras sagittis rutrum ipsum, eget elementum arcu bibendum vitae",
"Sed laoreet dignissim purus, ac vehicula eros lobortis id. Curabitur i",
"egestas non arcu. Quisque placerat vulputate magna",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"Praesent lacinia pellentesque sapien",
};
จากนั้นที่เมธอด onCreate()
ก็จัดการสร้าง ArrayAdapter
พร้อมทั้งให้ setAdapter
ให้ ListView
แบบนี้
public class SwipeToRefreshActivity extends ActionBarActivity {
private SwipeRefreshLayout mSwipeRefresh;
private ListView mListView;
private ArrayAdapter<String> mSimpleAdapter;
private ArrayList<String> mData = new ArrayList<String>();
private Random random = new Random();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
initSampleData();
mSimpleAdapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, android.R.id.text1, mData);
mListView.setAdapter(mSimpleAdapter);
}
}
ส่วน listener ของ SwipeRefreshLayout
ก็เพิ่มนี้ลงไป เพื่อให้ ListView ทำการ random ข้อมูลใหม่ เมื่อมีการ refresh
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mSimpleAdapter.clear();
initSampleData();
mSimpleAdapter.notifyDataSetChanged();
mSwipeRefresh.setRefreshing(false);
}
});
mSimpleAdapter.clear()
คือสั่งให้ ลบข้อมูลใน ListView ท้ิงก่อน จากนั้นก็ทำการ initSampleData ใหม่อีกครั้ง แล้วก็สั่ง notifyDataSetChanged()
เพื่อทำการ refresh ค่าที่เปลี่ยนแปลงใน Adapter
จากนั้น ก็สั่งให้ SwipeRefreshLayout
หยุดการ refresh ด้วยคำสั่ง #setRefreshing(false)
สุดท้าย หากเราไม่ชอบ ไอ้ตัว Progress สีดำๆ เทาๆ เราก็สามารถเปลี่ยนมันได้ ด้วยเมธอด setColorSchemeColors
โดยรับ paramter เป็นสี 4 ค่า คิดว่าน่าจะเรียงลำดับก่อนหลัง แบบนี้
mSwipeRefresh.setColorSchemeColors(Color.parseColor("#4183D7"),
Color.parseColor("#F62459"),
Color.parseColor("#03C9A9"),
Color.parseColor("#F4D03F"));
ทดสอบรันโปรแกรมอีกครั้ง แต่ว่า เราเห็นแค่สี หรือสองทีเท่านั้นเอง เนื่องจากว่า มัน refresh เสร็จก่อนที่จะแสดงสีอื่นๆ ฉะนั้น ผมเลยเพิ่ม delay ให้มันนิดนึง เพื่อที่จะได้เห็น progress ทุกๆสี แบบนี้
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override public void run() {
mSimpleAdapter.clear();
initSampleData();
mSimpleAdapter.notifyDataSetChanged();
mSwipeRefresh.setRefreshing(false);
}
}, 5000);
}
});
ด้านบนเป็นการใช้ Handler
และ Runnable
เข้ามาช่วยคือเมื่อ SwipeRefreshLayout
ทำการ refresh แล้ว ก็จะรอ 5 วินาที ถึงจะทำการ initSampleData ทำให้เราสามารถเห็น progress bar ได้ทุกสี
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit