Material Design用戶界面指南中很是棒的一個設計是Swipe to Refresh UI pattern。實際上你可能已經看到或者用過這種效果了。在不少熱門的app中都有這種效果,比facebok、 Google Newsstand, Trello, Gmail等等。html
相似於以下效果:
android
Swipe to Refresh UI很是適合於基於adapter的控件(如RecyclerView and ListView),通常它們都須要支持用戶的刷新請求。關於Swipe to Refresh的 實現,在KitKat版本中就有了SwipeRefreshLayout,Lollipop中對SwipeRefreshLayout作了改進,v4包含 了SwipeRefreshLayout控件,咱們只需作一些設置就能夠了。爲了方便讀者,我把demo放在了github 上 下載地址。git
咱們是在一個包含最新版本Support庫的Android Studio項目中實現Swipe to Refresh,咱們要作的第一件事就是將support library添加進build.gradle
:github
1
|
compile
'com.android.support:support-v4:21.0.+'
|
在新建工程嚮導的時候自動建立了res/layouts/activity_main.xml
文件,咱們將一個ListView添加進SwipeRefreshLayout控件web
1
2
3
4
5
6
7
8
9
10
11
|
<android.support.v4.widget.SwipeRefreshLayout
android:id=
"@+id/activity_main_swipe_refresh_layout"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<ListView
android:id=
"@+id/activity_main_listview"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
|
注 意ListView被包含在了SwipeRefreshLayout的裏面。每次咱們滑動ListView到SwipeRefreshLayout邊緣的 時候,SwipeRefreshLayout都會顯示一個正在加載的圖標,同時觸發一個onRefresh事件。onRefresh是咱們爲本身list 刷新數據添加的一個回調方法。api
設置adapter
app
佈局咱們已經搞定,如今爲列表添加數據,咱們用一個簡單的adapter來顯示數據,數據來自於res/strings.xml
文件:dom
1
2
3
4
5
6
7
8
9
10
11
|
<string-array name=
"cat_names"
>
<item>George</item>
<item>Zubin</item>
<item>Carlos</item>
<item>Frank</item>
<item>Charles</item>
<item>Simon</item>
<item>Fezra</item>
<item>Henry</item>
<item>Schuster</item>
</string-array>
|
設置adapter:async
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class MainActivity extends Activity {
ListView mListView;
SwipeRefreshLayout mSwipeRefreshLayout;
Adapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.acivity_main);
SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
mListView = findViewById(R.id.activity_main_list_view);
mListView.setAdapter(
new
ArrayAdapter<String>(){
String[] fakeTweets = getResources().getStringArray(R.array.fake_tweets);
mAdapter =
new
ArrayAdapter<String>(
this
, android.R.layout.simple_list_item_1, fakeTweets)
listView.setAdapter(mAdapter);
});
}
}
|
處理數據刷新
ide
adapter 已經設置,如今咱們添加下拉刷新事件。咱們會免費得到一個動畫效果的加載圖標,咱們只須要決定ListView該作什麼,這取決於 SwipeRefreshLayout的OnRefreshListener 接口是如何實現的。咱們用getNewCatNames模擬從webservice 中獲得新數據。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@Override
public void onCreate(Bundle savedInstanceState) {
...
listView.setAdapter();
mSwipeRefreshLayout.setOnRefreshListener(
new
SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshContent();
...
}
// fake a network operation's delayed response
// this is just for demonstration, not real code!
private void refreshContent(){
new
Handler().postDelayed(
new
Runnable() {
@Override
public void run() {
mAdapter =
new
ArrayAdapter<String>(MainActivity.
this
, android.R.layout.simple_list_item_1, getNewCatNames());
mListView.setAdapter(mAdapter);
mSwipeRefreshLayout.setRefreshing(
false
);
});
}
// get new cat names.
// Normally this would be a call to a webservice using async task,
// or a database operation
private List<String> getNewCatNames() {
List<String> newCatNames =
new
ArrayList<String>();
for
(int i = 0; i < mCatNames.size(); i++) {
int randomCatNameIndex =
new
Random().nextInt(mCatNames.size() - 1);
newCatNames.add(mCatNames.get(randomCatNameIndex));
}
return
newCatNames;
}
|
注意上面的代碼中refreshContent()
方法最後一行代碼setRefreshing(false);
setRefreshing
的做用是設置刷新加載效果的icon是否繼續顯示,這裏使用handler作了個延時,模擬實際加載數據須要的時間,當handler的post開始執行的時候setRefreshing(false)
表示加載結束,中止播放加載動畫。
自定義
你能夠自定義SwipeRefreshLayout的外觀。setColorSchemeResources()
能夠改變加載圖標的顏色。
先在資源文件中定義幾個顏色值:
1
2
3
4
5
|
<resources>
<color name=
"orange"
>
#FF9900</color>
<color name=
"green"
>
#009900</color>
<color name=
"blue"
>
#000099</color>
</resources>
|
而後調用setColorSchemeResources(R.color.orange, R.color.green, R.color.blue);
SwipeRefreshLayout旋轉的時候將會在這三種顏色間切換。
就如你所看到的Swipe to Refresh簡化了用戶請求更新數據的操做,關於SwipeRefreshLayout的更多api請查看官方文檔。
注:本篇文章提供的demo編譯的時候雖然用的是21版本的appcompat,可是運行仍是須要在5.0的設備上,由於demo的Material主題和顏色appcompat無能爲力。固然你能夠以下更改一下主題,這樣在4.x版本上也能運行:
demo原本的主題:
styles.xml
1
2
3
4
5
6
7
|
<resources>
<!-- Base application theme. -->
<style name=
"AppTheme"
parent=
"android:ThemeOverlay.Material.Light"
>
<!-- Customize your theme here. -->
<item name=
"android:colorPrimary"
>@android:color/holo_blue_dark</item>
</style>
</resources>
|
改爲:
1
2
3
4
5
6
7
|
<resources>
<!-- Base application theme. -->
<style name=
"AppTheme"
parent=
"Theme.AppCompat.Light"
>
<!-- Customize your theme here. -->
</style>
</resources>
|
http://design.1sters.com/