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/