MyTetra Share
Делитесь знаниями!
Android Fragment. Что это?
22.04.2017
11:27
Текстовые метки: Fragment
Раздел: Android - Разное

Android Fragment. Что это?

В этом уроке, я хочу объяснить, что такое Fragment и почему его нужно использовать. Мы рассмотрим немного теории, а также практический пример применения Fragments.

Скачать

Представьте себе пазл, который вы можете сложить и получить общий вид картинки, именно так можно представить Fragment. Или же если вы работали разработкой сайтов, а именно PHP то вам знакома возможность подключать общие части сайта например меню как отдельного блока с помощью include.

 

Шаг 0. Теория

Так как определение не совсем понятно, я решил сказать своими словами его.

Fragment (Фрагмент) — по сути это подобие Activity, которое мы можем подключать в разные части приложения. Но одно Activity может содержать несколько fragment.

Фрагменты появились в API 11 (Android 3.0) для поддержки на более старых версиях был доработан Android Support library.

Также важно понимать, что фрагменты — это не замена активности, они не могут существовать сами по себе, а только вместе с Activity. Поэтому в AndroidManifest регистрировать Fragments не нужно.

 

Шаг 1. Создаем проект

Давайте создадим простой проект, пока без использования Fragment-ов. Создаем Android Gradle Project:


Теперь создадим Activity в пакете com.myfragmentexam.app назовем его MainActivity:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

package com.myfragmentexam.app;

 

import android.app.Activity;

import android.os.Bundle;

 

public class MainActivity extends Activity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_layout);

    }

}

Для этого activity нам нужно создать layout, создаем в res/layout новый layout и называем егоmain_layout:

?

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

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

 

    <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="Кнопка 1"

            android:id="@+id/button" android:layout_marginTop="20dp"/>

    <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="Кнопка 2"

            android:id="@+id/button2"/>

    <CheckBox

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Новый компонент 1"

            android:id="@+id/checkBox" android:layout_gravity="center_horizontal" android:checked="false"

            android:layout_marginTop="20dp"/>

    <CheckBox

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Новый компонент 2"

            android:id="@+id/checkBox2" android:layout_gravity="center_horizontal" android:checked="false"/>

    <ImageView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:id="@+id/imageView" android:layout_gravity="center_horizontal"

            android:src="@drawable/android_img"

            android:layout_marginTop="20dp"/>

</LinearLayout>

Как видите в 33-й строке мы указываем на ресурс изображения, для этого вам нужно в res/drawableдобавить следующее изображение:


Последним шагом нужно зарегистрировать activity MainActivity в AndroidManifest.xml:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.myfragmentexam.app">

 

    <application android:allowBackup="true"

        android:label="@string/app_name"

        android:icon="@drawable/ic_launcher"

        android:theme="@style/AppTheme">

 

        <activity android:name=".MainActivity">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

 

    </application>

 

</manifest>

Начиная с 9-й строки мы регистрируем Activity в контексте.

Теперь запустим. Мы должны увидеть следующее:


Пока это простое приложение, которое не выполняет никакой логики и не имеет фрагментов.

 

Шаг 2. Делим на части

Особеность Fragment-ов в том, что вы можите разбить внешний вид на блоки и потом подключать их для отображения на разных стройствах по своему (смартфон/планшет). Также мы получим возможность переиспользования блоков(Fragments).

Первыйм делом вынесем кнопки в отдельный фрагмент, в res/layout создаем новый layout и называем егоbutton_fragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

 

    <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="Кнопка 1"

            android:id="@+id/button" android:layout_marginTop="20dp"/>

    <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="Кнопка 2"

            android:id="@+id/button2"/>

 

</LinearLayout>

Выглядеть это будет так:


 

Теперь вынесем CheckBox-сы в отдельный layout назовем его checkbox_fragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

 

    <CheckBox

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Новый компонент 1"

            android:id="@+id/checkBox" android:layout_gravity="center_horizontal" android:checked="false"

            android:layout_marginTop="20dp"/>

    <CheckBox

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Новый компонент 2"

            android:id="@+id/checkBox2" android:layout_gravity="center_horizontal" android:checked="false"/>

 

</LinearLayout>

Выглядеть это будет так:


 

И вынесем картинку в layout назвав его image_fragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

 

    <ImageView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:id="@+id/imageView" android:layout_gravity="center_horizontal"

            android:src="@drawable/android_img"

            android:layout_marginTop="20dp"/>

 

</LinearLayout>

Выглядеть это будет так:


 

Шаг 3. Создаем Fragments

Мы поделили наш первоначальный вид на части, теперь давайте создадим на их основе фрагменты.

Посмотрите на структуру классов ниже и на её основе создайте пакет fragments и в нем классы классы ButtonFragmentCheckBoxFragmentImageFragment.

 

Для того чтобы все эти классы стали фрагментами их нужно унаследовать от класса Fragment. Обратите внимание что класс фрагмент мы будем использовать не со стандартной библиотеки android.app, а с android.support.v4.app.

Причина этого то что фрагменты в вспомогательном пакете более лучше поддерживаются и если сравнивать со стандартным, то он не имеет тех багов, которые имеет стандартный пакет(android.app).

В Activity мы подключали layout в методе onCreate() через метод setContentView(). Но в фрагментах метод onCreate() используется немного для других целей. Поэтому для подключения layout используется отдельный метод onCreateView().

 

Давайте начнем с ButtonFragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package com.myfragmentexam.app.fragments;

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import com.myfragmentexam.app.R;

 

public class ButtonFragment extends Fragment {

 

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

                             Bundle savedInstanceState) {

         

        View viewHierarchy = inflater.inflate(R.layout.button_fragment, container, false);

         

        return viewHierarchy;

    }

}

Теперь детальней рассмотрим что же мы тут делаем.

LayoutInflater —  позволяет построить нужный макет, считывая информацию из указанного XML-файла.

Обратите внимание на то что 16-й строке в метод inflate() мы передаем 3 параметра разметку нашуго фрагмента, контейнер, и значение (true |false), которое указывает на возможнось подключения фрагментов в Activity через контейнер. Мы указали false так как сами создаем блоки для фрагментов.

 

Теперь по аналогии создадим реализацию для фрагмента CheckBoxFragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package com.myfragmentexam.app.fragments;

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import com.myfragmentexam.app.R;

 

public class CheckBoxFragment extends Fragment {

 

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

                             Bundle savedInstanceState) {

 

        View viewHierarchy = inflater.inflate(R.layout.checkbox_fragment, container, false);

 

        return viewHierarchy;

    }

 

}

 

И для последнего ImageFragment:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package com.myfragmentexam.app.fragments;

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import com.myfragmentexam.app.R;

 

public class ImageFragment extends Fragment {

 

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

                             Bundle savedInstanceState) {

 

        View viewHierarchy = inflater.inflate(R.layout.image_fragment, container, false);

 

        return viewHierarchy;

    }

}

 

Шаг 4. Собираем все в кучу

Мы создали пачку фагментов, но что с ними делать? Их мы теперь можем подключать в те места куда нам нужно. Для примера мы переделаем MainActivity и main_layout под фрагменты.

Для начало давайте модифицируем MainActivity:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package com.myfragmentexam.app;

 

import android.os.Bundle;

import android.support.v4.app.FragmentActivity;

 

public class MainActivity extends FragmentActivity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_layout);

    }

 

}

Обратите на строку 6, как видите мы наследуемся не просто от Activity, а от FragmentActivity это нужно делать когда вы используете Fragment с пакета android.support.v4.app.

Теперь модифицируем layout для нашего Activity, а именно main_layout:

?

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

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="fill_parent"

              android:layout_height="fill_parent">

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ButtonFragment"

            android:id="@+id/button_fragment"

            android:layout_height="wrap_content"

            android:layout_width="match_parent"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.CheckBoxFragment"

            android:id="@+id/checkbox_fragment"

            android:layout_height="wrap_content"

            android:layout_width="match_parent"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ImageFragment"

            android:id="@+id/image_fragment"

            android:layout_weight="1"

            android:layout_height="0dp"

            android:layout_width="match_parent"/>

 

</LinearLayout>

Обратите внимание на выделенные строки, тут мы указываем какой фрагмент подключать.

Но теперь в Intellij IDEA режим Preview работает не корректно:


Для того чтобы это исправить нам нужно немного модифицировать main_layout:

?

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

<?xml version="1.0" encoding="utf-8"?>

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              xmlns:tools="http://schemas.android.com/tools"

              android:orientation="vertical"

              android:layout_width="fill_parent"

              android:layout_height="fill_parent">

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ButtonFragment"

            android:id="@+id/button_fragment"

            android:layout_height="wrap_content"

            android:layout_width="match_parent"

            tools:layout="@layout/button_fragment"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.CheckBoxFragment"

            android:id="@+id/checkbox_fragment"

            android:layout_height="wrap_content"

            android:layout_width="match_parent"

            tools:layout="@layout/checkbox_fragment"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ImageFragment"

            android:id="@+id/image_fragment"

            android:layout_weight="1"

            android:layout_height="0dp"

            android:layout_width="match_parent"

            tools:layout="@layout/image_fragment"/>

 

</LinearLayout>

На выделенных строках видно изменения, таким образом мы указали фрагментам на нашем layout какие layout они отображают.

И теперь режим Preview работает корректно:


После этого, можно запустить и проверить. Вы должны увидеть тоже что показанно на Preview.

 

Шаг 5. Добавляем альбомный вид

Для этого создаем в res папке layout-land и копируем в в него все содержимое папки layout.

После этого немного изменим расположение фрагментов на main_layout. Обратите внимение, что мы будем менять расположение фрагментов, а не их компонентов, что довольно таки удобно.

?

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

<?xml version="1.0" encoding="utf-8"?>

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

                xmlns:tools="http://schemas.android.com/tools"

                android:orientation="horizontal"

                android:layout_width="fill_parent"

                android:layout_height="fill_parent">

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ButtonFragment"

            android:id="@+id/button_fragment"

            android:layout_height="wrap_content"

            android:layout_width="match_parent"

            tools:layout="@layout/button_fragment"

            android:layout_alignParentLeft="true"

            android:layout_marginLeft="15dp"

            android:layout_alignParentTop="true"

            android:layout_toLeftOf="@+id/image_fragment"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.CheckBoxFragment"

            android:id="@+id/checkbox_fragment"

            android:layout_height="wrap_content"

            android:layout_width="wrap_content"

            tools:layout="@layout/checkbox_fragment"

            android:layout_below="@+id/button_fragment"

            android:layout_alignParentLeft="true"

            android:layout_alignParentStart="true"

            android:layout_toLeftOf="@+id/image_fragment"

            android:layout_marginLeft="15dp"/>

 

    <fragment

            android:name="com.myfragmentexam.app.fragments.ImageFragment"

            android:id="@+id/image_fragment"

            android:layout_height="wrap_content"

            android:layout_width="wrap_content"

            tools:layout="@layout/image_fragment"

            android:layout_alignParentTop="true"

            android:layout_alignParentRight="true"

            android:layout_alignParentEnd="true"

            android:layout_marginRight="15dp"

            android:layout_marginLeft="15dp"/>

 

</RelativeLayout>

Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования