Статьи

Учебник по Android SwipeRefreshLayout

В этом посте мы опишем компонент SwipeRefreshLayout . Этот компонент должен использоваться всякий раз, когда пользователь может обновить пользовательский интерфейс, используя жест смахивания . В предыдущем посте мы говорили о другом методе обновления пользовательского интерфейса, который мы назвали Shake для обновления , когда пользователь встряхивает свой смартфон и с помощью датчика акселерометра приложение обновляет пользовательский интерфейс. Мы говорили о пользовательской реализации этого шаблона обновления в этом посте, где мы реализовали некоторые подобные.

Компонент SwipeRefreshLayout является стандартной реализацией, предоставляемой SDK, и он уже используется в некоторых приложениях, предоставляемых Android (например, Gmail).

Вступление

Этот компонент принимает только один дочерний элемент: тот, который мы хотим обновить. Он использует механизм слушателя, чтобы информировать слушателя, который содержит этот компонент, о том, что произошло событие обновления, поэтому, другими словами, наша Деятельность, например, должна реализовать интерфейс для уведомления. Деятельность отвечает за обработку события обновления и обновление соответствующего представления. Если слушатель, как только он получает событие, определяет, что процесс обновления должен иметь место, и хочет показать «анимацию обновления», он должен вызвать setRefrshing(true) , в противном случае он может отменить анимацию, вызвав setRefreshing(false) .

Как использовать SwipeRefreshLayout

Теперь мы знаем, как работает этот компонент, и создадим простой пример, чтобы показать, как его использовать. Предположим, мы хотим сгенерировать случайное число, так как пользователь использует жест вертикальной прокрутки:

android_swipetorefreshlayout [5]

Обычно этот компонент является корневым компонентом:

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, но и другие элементы, давайте предположим, что у нас есть такой интерфейс:

android_swipetorefreshlayout_listview [4]

Этот случай немного сложнее, потому что, если мы прокручиваем элементы в 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 .