Добрый день. Сегодня я хотел бы показать вам небольшой и достаточно простой пример использования 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);
}
}
}
}