Добрый день. Сегодня я хотел бы показать вам небольшой и достаточно простой пример использования Fragments. Я надеюсь он будет полезен тем, кто только начал знакомиться с принципами работы Fragments. Изначально, фрагменты были реализованы начиная с Android 3.0 для более динамичного проектирования пользовательских интерфейсов.
Вкратце, Fragment схож с Activity, у них обоих есть свой собственный жизненный цикл. Однако Fragment не может существовать вне Activity. Можно использовать для одного и того же Activity разные Fragments что придает гибкость и вариативность в процессе разработки.
Больше про Fragments можно прочесть здесь:
Fragments. Android Developer
Перейдем же наконец к практике. Напишем небольшую тренировочную программу, в которой будут использоваться фрагменты. При вертикальном положении экрана сначала будет выведен статический список ссылок и при нажатии на ссылку, будет запускаться Activity, отображающее содержимое веб-страницы по выбранной ссылке. При горизонтальном положении экрана, список ссылок и содержимое веб-страницы будут размещаться во Fragments и отображаться одновременно. Схема работы приложения выглядит следующим образом:

Напишем класс FragmentActivity, именно с него начинается работа приложения:
Далее необходимо создать layout в файле fragment.xml для вертикальной и горизонтальной ориентации экрана, который используется в классе FragmentActivity. Для горизонтальной ориентации определим два фрагмента, каждый будет занимать по половине ширины экрана устройства. Содержимое файла /res/layout-land/fragment.xml для горизонтальной ориентации экрана:
Содержимое файла /res/layout/fragment.xml для вертикальной(портретной) ориентации экрана:
Опишем layout файл /res/layout/fragment_detail_activity.xml для Activity, которое будет отображать содержимое веб-страницы в вертикальной(портретной) ориентации:
Сам класс Activity. В нем считываем полученную через extras ссылку и отображаем в WebView содержимое веб-страницы. Данное Activity вызывается в вертикальной ориентации:
Класс FragmentList самый объемный, но не сложный в реализации. В функции onListItemClick мы проверяем наличие FragmentDetail с WebView. Если такой фрагмент существует, то вызываем его функцию goToLink(String link), которая загружает веб-страницу. В противном случае, если фрагмента не существует, то вызывается FragmentDetailActivity, в которое передается ссылка через extras.
Опишем класс FragmentDetail, он будет служить для отображения содержимого веб-страницы в WebView. В частности, отображением занимается функция goToLink(String link), она вызывается в классе FragmentList.
Файл fragment_detail.xml
Ну вот и все. Теперь запустим наше приложение. Результат работы должен быть следующим:



Спасибо за внимание.
UPDATE 1:
Спасибо пользователю vtimashkov за дельное замечание, которое находится в первом комментарии к статье. Ниже приведу код, решающий данную проблему,.
Итак, для начала внесем в файл AndroidManifest следующие изменения:
Это позволит нам контролировать изменение ориентации экрана в FragmentDetailActivity. Далее изменим функциональность класса FragmentDetailActivity. Сохраняем текущую ссылку в переменную currentLink. Функция onConfigurationChanged вызывается при смене ориентации экрана. В ней, проверяем, если мы попали с вертикального режима в горизонтальный, то запускаем FragmentActivity и передаем в него текущую ссылку.
И наконец наш FragmentActivity. Сперва проверяем, получили ли мы ссылку в extras. Если да, то это означает, что мы перешли в FragmentDetailActivity в горизонтальный режим и теперь отображаем содержимое веб-страницы в.
Вкратце, Fragment схож с Activity, у них обоих есть свой собственный жизненный цикл. Однако Fragment не может существовать вне Activity. Можно использовать для одного и того же Activity разные Fragments что придает гибкость и вариативность в процессе разработки.
Больше про Fragments можно прочесть здесь:
Fragments. Android Developer
Перейдем же наконец к практике. Напишем небольшую тренировочную программу, в которой будут использоваться фрагменты. При вертикальном положении экрана сначала будет выведен статический список ссылок и при нажатии на ссылку, будет запускаться Activity, отображающее содержимое веб-страницы по выбранной ссылке. При горизонтальном положении экрана, список ссылок и содержимое веб-страницы будут размещаться во Fragments и отображаться одновременно. Схема работы приложения выглядит следующим образом:

Напишем класс FragmentActivity, именно с него начинается работа приложения:
public class FragmentActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment); } }
Далее необходимо создать layout в файле fragment.xml для вертикальной и горизонтальной ориентации экрана, который используется в классе FragmentActivity. Для горизонтальной ориентации определим два фрагмента, каждый будет занимать по половине ширины экрана устройства. Содержимое файла /res/layout-land/fragment.xml для горизонтальной ориентации экрана:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <fragment class="com.example.hellopeacefullworld.FragmentList" android:id="@+id/fragment_list" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" > </fragment> <fragment class="com.example.hellopeacefullworld.FragmentDetail" android:id="@+id/fragment_detail" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" > </fragment> </LinearLayout>
Содержимое файла /res/layout/fragment.xml для вертикальной(портретной) ориентации экрана:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <fragment class="com.example.hellopeacefullworld.FragmentList" android:id="@+id/fragment_list" android:layout_width="match_parent" android:layout_height="match_parent" > </fragment> </LinearLayout>
Опишем layout файл /res/layout/fragment_detail_activity.xml для Activity, которое будет отображать содержимое веб-страницы в вертикальной(портретной) ориентации:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <fragment class="com.example.hellopeacefullworld.FragmentDetail" android:id="@+id/fragment_detail" android:layout_width="match_parent" android:layout_height="match_parent" > </fragment> </LinearLayout>
Сам класс Activity. В нем считываем полученную через extras ссылку и отображаем в WebView содержимое веб-страницы. Данное Activity вызывается в вертикальной ориентации:
public class FragmentDetailActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_detail_activity); Bundle extras = getIntent().getExtras(); String s = extras.getString("selectedValue"); WebView viewer = (WebView) findViewById(R.id.webView1); viewer.loadUrl(s); } }
Класс FragmentList самый объемный, но не сложный в реализации. В функции onListItemClick мы проверяем наличие FragmentDetail с WebView. Если такой фрагмент существует, то вызываем его функцию goToLink(String link), которая загружает веб-страницу. В противном случае, если фрагмента не существует, то вызывается FragmentDetailActivity, в которое передается ссылка через extras.
public class FragmentList extends ListFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); String[] values = new String[] { "http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/80s-phone-app-slicing/", "http://mobile.tutsplus.com/tutorials/corona/create-a-brick-breaker-game-with-the-corona-sdk-game-controls/", "http://mobile.tutsplus.com/articles/news/best-of-tuts-in-february-2011/"}; ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, values); setListAdapter(adapter); } @Override public void onListItemClick(ListView l, View v, int position, long id) { String item = (String) getListAdapter().getItem(position); FragmentDetail fragment = (FragmentDetail)getFragmentManager().findFragmentById(R.id.fragment_detail); if (fragment != null && fragment.isInLayout()) { fragment.goToLink(item); } else { Intent intent = new Intent(getActivity().getApplicationContext(), FragmentDetailActivity.class); intent.putExtra("selectedValue", item); startActivity(intent); } } }
Опишем класс FragmentDetail, он будет служить для отображения содержимого веб-страницы в WebView. В частности, отображением занимается функция goToLink(String link), она вызывается в классе FragmentList.
public class FragmentDetail extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_detail, container, false); return view; } public void goToLink(String item){ WebView viewer = (WebView)getView().findViewById(R.id.webView1); viewer.loadUrl(item); } }
Файл fragment_detail.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Ну вот и все. Теперь запустим наше приложение. Результат работы должен быть следующим:



Спасибо за внимание.
UPDATE 1:
Спасибо пользователю vtimashkov за дельное замечание, которое находится в первом комментарии к статье. Ниже приведу код, решающий данную проблему,.
Итак, для начала внесем в файл AndroidManifest следующие изменения:
<activity android:name=".FragmentDetailActivity" android:configChanges="orientation|screenSize|keyboardHidden"></activity>
Это позволит нам контролировать изменение ориентации экрана в FragmentDetailActivity. Далее изменим функциональность класса FragmentDetailActivity. Сохраняем текущую ссылку в переменную currentLink. Функция onConfigurationChanged вызывается при смене ориентации экрана. В ней, проверяем, если мы попали с вертикального режима в горизонтальный, то запускаем FragmentActivity и передаем в него текущую ссылку.
public class FragmentDetailActivity extends Activity { String currentLink; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_detail_activity); Bundle extras = getIntent().getExtras(); currentLink = extras.getString("selectedValue"); WebView viewer = (WebView) findViewById(R.id.webView1); viewer.loadUrl(currentLink); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Intent intent = new Intent(this, FragmentActivity.class); intent.putExtra("selectedValue", currentLink); startActivity(intent); } } }
И наконец наш FragmentActivity. Сперва проверяем, получили ли мы ссылку в extras. Если да, то это означает, что мы перешли в FragmentDetailActivity в горизонтальный режим и теперь отображаем содержимое веб-страницы в.
public class FragmentActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment); FragmentDetail fragment = (FragmentDetail)getFragmentManager().findFragmentById(R.id.fragment_detail); Bundle extras = getIntent().getExtras(); if(extras != null){ String link = extras.getString("selectedValue"); if(link !=null && fragment != null && fragment.isInLayout()){ fragment.goToLink(link); } } } }
