在以前版本的 Gmail 應用中,ActionBar 上有個刷新菜單,點擊一下刷新菜單變成一個轉圈的刷新標示動畫圖片。 之前實現該功能的時候都是使用一個類庫 RefreshActionItem 來實現的。RefreshActionItem 還支持一些擴展功能,功能比較豐富。
今天無意中又發現一個簡單的實現方式。如果您只需要一個刷新的效果,則可以考慮這種方法, 實現方式如下:
1. 首先定義一個 Menu xml 文件:
1
2
3
4
5
6
7
8
9
10
11
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
item
android:id
=
"@id/menu_refresh"
android:icon
=
"@drawable/icon_refresh"
android:orderInCategory
=
"100"
android:showAsAction
=
"always"
android:title
=
"@string/action_refresh"
/>
</
menu
>
|
2. 然后創建一個代表刷新進度的自定義 ProgressBar 布局文件 actionbar_indeterminate_progress.xml:
1
2
3
4
5
6
7
8
9
10
|
android:layout_height
=
"wrap_content"
android:layout_width
=
"56dp"
android:minWidth
=
"56dp"
>
<
ProgressBar
android:layout_width
=
"32dp"
android:layout_height
=
"32dp"
android:layout_gravity
=
"center"
style
=
"?indeterminateProgressStyle"
/>
</
FrameLayout
>
|
注意,為了顯示美觀,上面的 寬度和高度 不同的版本和屏幕可能需要設置不一樣的值,可以在不同的 dimens.xml 中設置。
3. 在 Activity 代碼中,獲取到該 MenuItem 並根據刷新情況來設置 ActionView:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
private
Menu mOptionsMenu;
@Override
public
boolean
onCreateOptionsMenu(Menu menu) {
mOptionsMenu = menu;
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_content, menu);
return
true
;
}
public
void
setRefreshActionButtonState(
boolean
refreshing) {
if
(mOptionsMenu ==
null
) {
return
;
}
final
MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh);
if
(refreshItem !=
null
) {
if
(refreshing) {
MenuItemCompat.setActionView(refreshItem, R.layout.actionbar_indeterminate_progress);
}
else
{
MenuItemCompat.setActionView(refreshItem,
null
);
}
}
}
|
這里為了兼容 AppCompat (android 3.0 之前的版本)用了 MenuItemCompat 來設置 ActionView。
現在,根據您的刷新邏輯,只需要調用 setRefreshActionButtonState 函數就可以啟用刷新動畫了。
這種方式,值得一提的是, 如果你設置了 ActionView,則就是一個自定義 ActionItem,如果在 ActionView 中你不處理 OnClick 事件,則用戶點擊該菜單是沒響應的,這種行為剛好是應用需要的行為。