В этом посте мы опишем компонент SwipeRefreshLayout . Этот компонент должен использоваться всякий раз, когда пользователь может обновить пользовательский интерфейс, используя жест смахивания . В предыдущем посте мы говорили о другом методе обновления пользовательского интерфейса, который мы назвали Shake для обновления , когда пользователь встряхивает свой смартфон и с помощью датчика акселерометра приложение обновляет пользовательский интерфейс. Мы говорили о пользовательской реализации этого шаблона обновления в этом посте, где мы реализовали некоторые подобные.
Компонент SwipeRefreshLayout является стандартной реализацией, предоставляемой SDK, и он уже используется в некоторых приложениях, предоставляемых Android (например, Gmail).
Вступление
Этот компонент принимает только один дочерний элемент: тот, который мы хотим обновить. Он использует механизм слушателя, чтобы информировать слушателя, который содержит этот компонент, о том, что произошло событие обновления, поэтому, другими словами, наша Деятельность, например, должна реализовать интерфейс для уведомления. Деятельность отвечает за обработку события обновления и обновление соответствующего представления. Если слушатель, как только он получает событие, определяет, что процесс обновления должен иметь место, и хочет показать «анимацию обновления», он должен вызвать setRefrshing(true)
, в противном случае он может отменить анимацию, вызвав setRefreshing(false)
.
Как использовать SwipeRefreshLayout
Теперь мы знаем, как работает этот компонент, и создадим простой пример, чтобы показать, как его использовать. Предположим, мы хотим сгенерировать случайное число, так как пользователь использует жест вертикальной прокрутки:
Обычно этот компонент является корневым компонентом:
01
02
03
04
05
06
07
08
09
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
35
36
37
38
39
40
41
42
43
|
< android.support.v4.widget.SwipeRefreshLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" android:paddingBottom = "@dimen/activity_vertical_margin" android:id = "@+id/swipe" > < ScrollView android:layout_width = "match_parent" android:layout_height = "match_parent" > < RelativeLayout android:layout_width = "match_parent" android:layout_height = "match_parent" > < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Random number:" android:id = "@+id/lbl" /> < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:id = "@+id/rndNum" android:layout_toRightOf = "@id/lbl" /> < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_below = "@id/lbl" android:layout_centerHorizontal = "true" android:layout_marginTop = "20dp" android:text = "Swipe to Refresh" style = "@android:style/TextAppearance.Medium" /> </ RelativeLayout > </ ScrollView > </ android.support.v4.widget.SwipeRefreshLayout > |
Как видно из макета выше, SwipeRefreshLayout имеет только одного дочернего элемента. Теперь мы можем кодировать нашу активность:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
... @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) findViewById(R.id.swipe); final TextView rndNum = (TextView) findViewById(R.id.rndNum); swipeView.setColorScheme(android.R.color.holo_blue_dark, android.R.color.holo_blue_light, android.R.color.holo_green_light, android.R.color.holo_green_light); swipeView.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { swipeView.setRefreshing( true ); Log.d( "Swipe" , "Refreshing Number" ); ( new Handler()).postDelayed( new Runnable() { @Override public void run() { swipeView.setRefreshing( false ); double f = Math.random(); rndNum.setText(String.valueOf(f)); } }, 3000 ); } }); } .... |
Как вы можете видеть, в нашем примере все происходит в методе onCreate. В строке 6 мы получаем ссылку на SwipeRefreshLayout, чтобы мы могли установить прослушиватель (строка 10,11,12). В слушателе мы просто можем установитьRefreshing (true), чтобы включить обновление анимации, а затем мы генерируем наше случайное число. В конце (мы эмулируем довольно долгий процесс) мы прекращаем анимацию.
SwipeRefreshLayout с ListView
Другой интересный пример — как использовать SwipeRefreshLayout с ListView. Это интересный пример, потому что в реальном приложении часто возникает ситуация, когда у нас есть ListView, содержащий некоторые элементы, и мы хотим обновить их. Если ListView является единственным потомком SwipeRefreshLayout, у нас не будет никаких проблем, потому что все работает гладко. В некоторых случаях у нас есть не только ListView, но и другие элементы, давайте предположим, что у нас есть такой интерфейс:
Этот случай немного сложнее, потому что, если мы прокручиваем элементы в ListView вверх, все работает должным образом, но если прокрутить вниз, начинается процесс обновления, и элементы списка не прокручиваются так, как нам нужно. В этом случае мы можем использовать хитрость, мы можем отключить уведомление об обновлении с помощью setEnabled(false)
и включить его снова, как только первый элемент в ListView станет видимым:
01
02
03
04
05
06
07
08
09
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
35
36
37
38
39
40
|
@Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) findViewById(R.id.swipe); swipeView.setEnabled( false ); ListView lView = (ListView) findViewById(R.id.list); ArrayAdapter<String> adp = new ArrayAdapter<String>( this , android.R.layout.simple_list_item_1, createItems( 40 , 0 )); lView.setAdapter(adp); swipeView.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { swipeView.setRefreshing( true ); ( new Handler()).postDelayed( new Runnable() { @Override public void run() { swipeView.setRefreshing( false ); } }, 3000 ); } }); lView.setOnScrollListener( new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { } @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem == 0 ) swipeView.setEnabled( true ); else swipeView.setEnabled( false ); } }); } |
Как вы можете видеть в строке 33, мы переопределяем onScrollListener ListView для обработки механизма включения / выключения.
Ссылка: | Учебник по Android SwipeRefreshLayout от нашего партнера JCG Франческо Аццолы в блоге Surviving с Android . |