Избранное сообщение

Фетісов В. С. Комп’ютерні технології в тестуванні. Навчально-методичний посібник. 2-ге видання, перероблене та доповнене / Мои публикации

В 10-х годах я принимал участие в программе Европейского Союза Tempus "Освітні вимірювання, адаптовані до стандартів ЄС". В рамк...

Благодаря Интернету количество писателей и поэтов увеличивается в геометрической прогрессии. Поголовье читателей начинает заметно отставать.

среда, 28 сентября 2016 г.

Пример использования ViewFlipper в Android. Обзор контейнера ViewFlipper / Программирование на Java

В этом уроке мы познакомимся с особенностями контейнера 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:
Anim directory
Теперь создадим 4 новых xml файла Animation Resource File: res -> New -> Animation resource file:
animation
Речь идет о 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 проект можно по ссылке.

Комментариев нет:

Отправить комментарий