В этом уроке мы познакомимся с особенностями контейнера ViewFlipper
, а также напишем небольшое приложение с использованием ViewFlipper
. Следует отметить, что контейнер ViewFlipper в первую очередь создан для простой реализации слайдшоу или галереи, однако его очень удобно использовать в приложениях, где множество переходов и экранов (карточки больных со множеством форм ввода и т.п.).
Обзор контейнера ViewFlipper
Класс
ViewFlipper
наследует базовый класс ViewAnimator
, который делает переходы между двумя или более дочерними View
. На экране может быть показан только один дочерний View, остальные же будут показаны по нажатию или по истечению заданного времени, после чего ViewFlipper
пролистает к следующему по иерархии объекту View.
Анимации в ViewFlipper
ViewFlipper поддерживает анимацию перехода с одного экрана на другой. Это делается с помощью методов
setInAnimation()
и setOutAnimation()
, которые анимируют появление и затухание элементов View. Мы можем использовать анимацию по умолчанию Android системы или написать свой собственный класс анимации.
Переходы в ViewFlipper
Для контроля автоматического флипа (пролистывания) экранов приложения мы можем запускать и останавливать таймер на ViewFlipper контейнере. Управлять этим нам помогают методы
startFlipping()
и stopFlipping()
, а также метод setFlipInterval()
, который устанавливает интервал между пролистыванием экранов внутри ViewFlipper
.
Явно вызывать следующий или предыдущий экран позволяют методы
showNext()
иshowPrevious()
контейнера ViewFlipper
.Пример использования ViewFlipper в Android
Наше приложение будет состоять из 3х экранов. Мы сами будем обрабатывать события, связанные с переходами между экранами. Автоматический переход на следующий экран реализуется всего в одну строчку, а мы хотим попробовать как можно больше возможностей компонента
ViewFlipper
.1. Создание Android проекта
Первым делом создадим новый проект в Android Studio. Кто не знает как, то смотримпример здесь.
2. Анимация переходов
Теперь идем в папку res и создаем папку ресурсов для анимации: res -> New -> Android Resource Directory:
Теперь создадим 4 новых xml файла Animation Resource File: res -> New -> Animation resource file:
Речь идет о 2 xml для анимации появления объекта View на экране и его ухода с экранас левой стороны и такие же 2 анимации для появления/затухания с правой стороны:
Анимация появления слева
left_in.xml
:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="100%p"
android:toXDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>
|
Анимация ухода с экрана влево
left_out.xml
:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="-100%p" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
|
Такие же анимации для появления/ухода с экрана в право:
Анимация
right_in.xml
:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>
|
Анимация
right_out.xml
:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
|
Вкратце о тегах анимации:
<set>
— контейнер, который может содержать другие элементы анимаций.<translate>
— описывает вертикальное или горизонтальное движение. В нашем случае, горизонтальное, потому что мы описывали изменения по оси Ox.<alpha>
определяет появления/затухания анимации.
3. Макет с контейнером ViewFlipper
Теперь можем приступить к разметке контейнера
ViewFlipper
в макетеactivity_main.xml
:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/vf_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ua.com.prologistic.viewflippertestapp.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_previous_screen_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignTop="@+id/btn_next_screen_1"
android:text="Previous" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/btn_next_screen_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="Next" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_previous_screen_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignTop="@+id/btn_next_screen_2"
android:text="Previous" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/btn_next_screen_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="Next" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_previous_screen_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignTop="@+id/btn_next_screen_3"
android:text="Previous" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/btn_next_screen_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="Next" />
</RelativeLayout>
</ViewFlipper>
|
Как видите, в контейнере
ViewFlipper
3 дочерних RelativeLayout. в каждом из которых 2 виджета Button (следующий экран, TextView как индикатор текущего экрана и переход на предыдущий экран).4. Управление контейнером ViewFlipper в коде
Теперь давайте опишем наши виджеты в классе MainActivity:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package ua.com.prologistic.viewflippertestapp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ViewFlipper;
public class MainActivity extends AppCompatActivity {
private View.OnClickListener mOnClickListener;
private ViewFlipper mViewFlipper;
// кнопки налево и направо первого экрана
private Button mButtonPreviousScreen1;
private Button mButtonNextScreen1;
private Button mButtonPreviousScreen2;
private Button mButtonNextScreen2;
private Button mButtonPreviousScreen3;
private Button mButtonNextScreen3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mOnClickListener = new ClickListener();
mViewFlipper = (ViewFlipper) findViewById(R.id.vf_container);
mButtonNextScreen1 = (Button) findViewById(R.id.btn_next_screen_1);
mButtonPreviousScreen1 = (Button) findViewById(R.id.btn_previous_screen_1);
mButtonNextScreen2 = (Button) findViewById(R.id.btn_next_screen_2);
mButtonPreviousScreen2 = (Button) findViewById(R.id.btn_previous_screen_2);
mButtonNextScreen3 = (Button) findViewById(R.id.btn_next_screen_3);
mButtonPreviousScreen3 = (Button) findViewById(R.id.btn_previous_screen_3);
mButtonPreviousScreen1.setOnClickListener(mOnClickListener);
mButtonNextScreen1.setOnClickListener(mOnClickListener);
mButtonPreviousScreen2.setOnClickListener(mOnClickListener);
mButtonNextScreen2.setOnClickListener(mOnClickListener);
mButtonPreviousScreen3.setOnClickListener(mOnClickListener);
mButtonNextScreen3.setOnClickListener(mOnClickListener);
}
// перейти на предыдущий экран с анимацией справа налево
private void showPreviousScreen() {
// переход влево доступен только если мы не на первом экране
if (!isFirst()) {
mViewFlipper.setInAnimation(this, R.anim.right_in);
mViewFlipper.setOutAnimation(this, R.anim.right_out);
mViewFlipper.showPrevious();
}
}
// определяем, является ли текущий экран первым
private boolean isFirst() {
return mViewFlipper.getDisplayedChild() == 0;
}
// перейти на следующий экран с анимацией слева на право
private void showNextScreen() {
// переход вправо доступен только если мы не на последнем экране
if (!isLast()) {
mViewFlipper.setInAnimation(this, R.anim.left_in);
mViewFlipper.setOutAnimation(this, R.anim.left_out);
// переход вправо доступен
mViewFlipper.showNext();
}
}
// определяем, является ли текущий экран последним
private boolean isLast() {
return mViewFlipper.getDisplayedChild() + 1 == mViewFlipper.getChildCount();
}
private class ClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.btn_previous_screen_1) {
showPreviousScreen();
} else if (id == R.id.btn_next_screen_1) {
showNextScreen();
} else if (id == R.id.btn_previous_screen_2) {
showPreviousScreen();
} else if (id == R.id.btn_next_screen_2) {
showNextScreen();
} else if (id == R.id.btn_previous_screen_3) {
showPreviousScreen();
} else if (id == R.id.btn_next_screen_3) {
showNextScreen();
}
}
}
}
|
В коде мы определили кнопки, повешали слушатели и описали логику работу с контейнером
ViewFlipper
.
Теперь запустим приложение и посмотрим что получилось:
Ограничения, указанные в методе
showNext()
не дают нам пройти дальше третьего экрана. Такое же ограничение в методе showPrevious()
.
Под конец давайте рассмотрим другие атрибуты и возможности
ViewFlipper
, которые Вы можете применить в текущем проекте:- Атрибут
android:flipInterval
используется для задания интервала между автоматическим пролистыванием экранов внутри контейнера ViewFlipper. Задается в миллисекундах, например,android:flipInterval="3000"
. - Атрибут
android:autoStart
обозначает автоматический старт слайдшоу. Может принимать значенияtrue
илиfalse
. - Методы
startFlipping()
,stopFlipping()
,setFlipInterval(int milliseconds)
, отвечающие за старт слайдшоу, остановку слайдшоу и установку интервала между переходами соответственно.
Об остальных атрибутах и возможностях контейнера
ViewFlipper
читайте в документации.
Скачать готовый Android проект можно по ссылке.
Комментариев нет:
Отправить комментарий