The following tutorial demonstrates how to use
In portrait mode
In landscape mode
Fragments
. The entry Activity
(called MainActivity
of our application ) will use different layouts for portrait and for landscape mode.In portrait mode
MainActivity
will show one Fragment with a list of names. If the user touches an item in the list, a second Activity
called DetailActivity
will start and show the selected text.In landscape mode
MainActivity
will show two Fragments
. The first is again the Fragments
which shows the list of names. The second Fragment
shows the text of the current selected item. This is similar to the
portrait mode, but the whole information will be shown on one screen.
Create a new project
de.vogella.android.fragments
with an Activity
called MainActivity
.
Create or change the following layout files in the "res/layout/" folder.
First create the following file called "details.xml". This layout will be used by the
First create the following file called "details.xml". This layout will be used by the
DetailFragment
. <?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" > <TextView android:id="@+id/detailsText" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_horizontal|center_vertical" android:layout_marginTop="20dip" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" android:textSize="30dip" /> </LinearLayout>Change the existing "main.xml" file. This layout will be used by
MainActivity
in landscape mode and shows two Fragments
.<?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 android:id="@+id/listFragment" android:layout_width="150dip" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" class="de.vogella.android.fragments.ListFragment" ></fragment> <fragment android:id="@+id/detailFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="de.vogella.android.fragments.DetailFragment" > <!-- Preview: layout=@layout/details --> </fragment> </LinearLayout>
Create now the
Fragment
classes. Create the ListFragment
class.package de.vogella.android.fragments; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; public class ListFragment extends android.app.ListFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); String[] values = new String[] { "Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2" }; ArrayAdapter<String> adapter = new ArrayAdapter<String>(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); DetailFragment fragment = (DetailFragment) getFragmentManager() .findFragmentById(R.id.detailFragment); if (fragment != null && fragment.isInLayout()) { fragment.setText(item); } else { Intent intent = new Intent(getActivity().getApplicationContext(), DetailActivity.class); intent.putExtra("value", item); startActivity(intent); } } }Create the
DetailFragment
class.package de.vogella.android.fragments; import android.app.Fragment; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class DetailFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("Test", "hello"); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.details, container, false); return view; } public void setText(String item) { TextView view = (TextView) getView().findViewById(R.id.detailsText); view.setText(item); } }
We want that Android uses a different main.xml file in portrait model then in landscape mode.
For this reason create the "res/layout-port" folder.
In portrait mode Android will check the "layout-port" folder for fitting layout files. Only if we would not have a "main.xml" file in "layout-port", Android would check the "layout" folder.
Therefore create the following "main.xml" layout file in "res/layout-port".
For this reason create the "res/layout-port" folder.
In portrait mode Android will check the "layout-port" folder for fitting layout files. Only if we would not have a "main.xml" file in "layout-port", Android would check the "layout" folder.
Therefore create the following "main.xml" layout file in "res/layout-port".
<?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 android:id="@+id/listFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" class="de.vogella.android.fragments.ListFragment" /> </LinearLayout>Also create the "details_activity_layout.xml" layout file. This layout will be used in the
DetailActivity
which is only used in portrait mode. Please note that we could have
create this file also in the "layout" folder, but as it is only used in
portrait mode it is best practise to place it into this folder. <?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 android:id="@+id/detailFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="de.vogella.android.fragments.DetailFragment" /> </LinearLayout>
Create a new
Activity
called DetailActivity
with the following class.package de.vogella.android.fragments; import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; import android.widget.TextView; public class DetailActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Need to check if Activity has been switched to landscape mode // If yes, finished and go back to the start Activity if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { finish(); return; } setContentView(R.layout.details_activity_layout); Bundle extras = getIntent().getExtras(); if (extras != null) { String s = extras.getString("value"); TextView view = (TextView) findViewById(R.id.detailsText); view.setText(s); } } }
MainActivity
will remain unmodified.package de.vogella.android.fragments; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity {/** Called when the activity is first created. */@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Run your example. If you run the application in portrait mode you should see only one
Fragment
. Use Ctrl+F11 to switch the orientation. In horizontal mode you should see two Fragments
. If you select an item in portrait mode a new Activity
should get started with the selected item. In horizontal mode your second Fragment
should display the select item.
It show exception in DetailFragment fragment = (DetailFragment) getFragmentManager()
ReplyDelete.findFragmentById(R.id.detailFragment);
Cannot cast from Fragment to DetailFragment.
Please Help Me