Android: используем Fragments для оптимизации интерфейса

от автора

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

Больше про Fragments можно прочесть здесь:
Fragments. Android Developer

Перейдем же наконец к практике. Напишем небольшую тренировочную программу, в которой будут использоваться фрагменты. При вертикальном положении экрана сначала будет выведен статический список ссылок и при нажатии на ссылку, будет запускаться Activity, отображающее содержимое веб-страницы по выбранной ссылке. При горизонтальном положении экрана, список ссылок и содержимое веб-страницы будут размещаться во Fragments и отображаться одновременно. Схема работы приложения выглядит следующим образом:

image

Напишем класс 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> 

И наконец, опишем реализацию класса FragmentDetailActivity. Данное Activity будет вызываться при нажатии на ссылку в списке в портретном режиме. Данное Activity отображает в WebView содержимое веб-страницы.

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);  } } 

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


Спасибо за внимание.

ссылка на оригинал статьи http://habrahabr.ru/post/167315/