I'm developing an android application making use of fragments which is more of a Master/Detail form. I want the main activity to consist of a list fragment on the left side, based on the item chosen on the left i want to display a fragment with different layout on the right side.
(Note: each fragment on the right require different layouts/views)
All the examples that I've come across make use of only one common fragment on the right by changing some values in it or swapping/replacing new fragments having same layout.
If someone could shed some light on this problem then it will help me immensely. Thanks!
If you are using framelayouts to hold your fragments, it's the same as those other you mention. You just instantiate your fragment (whatever the layout) and swap it into the framelayout in place of the other one.
If you have hardcoded your fragments into the XML, you won't be able to do that (as far as I've been able to determine).
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frames"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/hline1"
android:layout_below="#id/horizontalline"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/leftpane"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight=".4" />
<TextView
android:id="#+id/verticalline"
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#color/bar_background"
android:gravity="center_horizontal"
android:paddingLeft="5dip"
android:paddingRight="5dip" />
<FrameLayout
android:id="#+id/rightpane"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
Then you use the id for the framelayout and the name of your instantiated fragment to put your fragment into the framelayout.
EventListFragment eventlist = new EventListFragment();
getFragmentManager().beginTransaction().replace(R.id.leftpane, eventlist).commit();
EventDetailFragment eventadd = new EventDetailFragment();
getFragmentManager().beginTransaction().replace(R.id.rightpane, eventadd).commit();
When you want to change the contents, you do the same thing again (the following would replace the fragment in the right pane with a new/different fragment, which can have it's own, different, layout associated with it):
EventSuperDetailFragment eventsuper = new EventSuperDetailFragment();
getFragmentManager().beginTransaction().replace(R.id.rightpane, eventsuper).commit();
Related
The layout of the app I am working on is the classical two-pane master-detail layout. In the leftpane the menu, in the rightpane the fragments that are shown as a result of pressing a menu item. One of the menu items initiates a ViewPager swiping structure. This ViewPager structure consists of a ScreenSlideActivity and a ScreenSlidePageFragment classes. The first class, as is standard, holds a pointer to the ViewPager object, the adapter (ScreenSlidePagerAdapter) with the essential methods like getItem and getFragment.
Everything works fine, except that the ViewPager occupies the entire screen, rather than in the right panel.
Question: how can I get the ViewPager to confine itself to the right panel, rather than occupying the entire screen?
Here is the layout of the two_pane, generated automatically by Eclipse when generating a master-detail template project:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".ItemListActivity" >
<!--
This layout is a two-pane layout for the Items
master/detail flow. See res/values-large/refs.xml and
res/values-sw600dp/refs.xml for an example of layout aliases
that replace the single-pane version of the layout with
this two-pane version.
For more on layout aliases, see:
http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/item_list"
android:name="com.company.ItemListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#android:layout/list_content" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginTop="10dip"
android:layout_marginBottom="20dip"
android:src="#drawable/icon" />
</LinearLayout>
<FrameLayout
android:id="#+id/item_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
The menu item that kicks off the ViewPager does this:
Intent intent = new Intent(this, ScreenSlideNewActivity.class);
startActivity(intent);
I found a hint to a solution from an old post here, but that's based on the deprecated ActivityGroup (solution at the bottom).
ActivityGroup or any other way to use activities inside other activities are deprecated.
You need to encapsulate your ViewPager structure inside a Fragment and not inside an Activity.
From there instead of starting your Activity with an Intent you will just pop your Fragment in place of your R.id.item_detail_container with a simple
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
ScreenSlideNewFragment fragment = new ScreenSlideNewFragment();
transaction.replace(R.id.item_detail_container, fragment);
transaction.commit();
Converting Activity to a Fragment is straight forward as the lifecycles are very similar.
i want to separate my layout in two parts:
the bottom for ads, and the other part to the app(few activities).
why i want to do that? because i want the ad appears every time even when new activity started.
http://i.stack.imgur.com/plVeO.png
i realized that is possible to do that with fragment.
I have few questions about fragment:
fragment can hold two activities?
can i start a fragment like activity with intent?
The main question is how TO SEPARATE THE LAYOUT IN TO PARTS while using fragment?
No, fragment can not have two Activities, but vise versa - yes. For dynamic actions with fragments create xml file in which will 2 frames, one attached to the bottom, and read about http://developer.android.com/guide/components/fragments.html, http://developer.android.com/reference/android/app/FragmentManager.html, http://developer.android.com/reference/android/app/FragmentTransaction.html
Try this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/frame1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:id="#+id/frame2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3" >
</FrameLayout>
</LinearLayout>
in Activity:
NewFragment fragment = new NewFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frame1, fragment);
ft.commit();
Or, static in xml:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ArticleFragment"
android:id="#+id/article_fragment"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
you could make one parent activity which will hold adverts and have free space for content, than you inherit that activity and fill up content from inherited one, maybe inflate other layouts in base. if you will be using more than one layout for content you could make also parent layout and "inherit" it as well.
or you can use one activity which would hold adverts and use fragments for content.
I am working in Android. My intention is to take 2 fragment containers like leftfragment and rightfragment in a main Fragment. And in left Fragment I will load folders and files. If I click on folder Item the right Fragment has to load the list of clicked folder items. I have done fine up to here.
Now when I am clicking on right fragment folder Item the current fragment should appear in Leftfragment without losing its state and the new items from the clicked folder has to appear at rightfragment. and again same like rightfragment to left and new content has to appear in rightfragment.
The main Fragment has the following layout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/left_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/hello_world" />
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#000000" />
<FrameLayout
android:id="#+id/right_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/hello_world" />
</LinearLayout>
Try using a temporary fragment in between to hold the right fragment while you replace it with the new detailed one. then you can replace the left fragment with the temporary fragment where you stored the right fragment.
Is it somehow possible to host two FragmentActivities in one layout?
For example, if I have following layout, can I host one FragmentActivity in container1 and one FragmentActivity in container2?:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/container1"
android:layout_width="match_parent"
android:layout_height="150dp" >
</FrameLayout>
<FrameLayout
android:id="#+id/container2"
android:layout_width="match_parent"
android:layout_height="150dp" >
</FrameLayout>
If this is not possible, can I have one FragmentActivity that loads two different fragments and displays one in container1 and one in container2?
You are a bit confused. Layouts doesn't contain activities, activities contain a layout. In your layout you can put Views and fragments, so yes, it is possible to load two fragments in one FragmentActivity, or rather it is the only way to achieve what you want.
I'm trying to replace a fragment in a composite layout. Here's my root layout XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/buttons"
android:name="com.kippygo.android.touch_talker.ButtonsFragment"
android:layout_width="200dp"
android:layout_height="match_parent"
class="com.kippygo.android.touch_talker.ButtonsFragment" >
<!-- Preview: layout=#layout/buttons_fragment -->
</fragment>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/buffer"
android:name="com.kippygo.android.touch_talker.BufferFragment"
android:layout_width="match_parent"
android:layout_height="80dp" >
<!-- Preview: layout=#layout/buffer_fragment -->
</fragment>
<FrameLayout
android:id="#+id/grid_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" >
</FrameLayout>
</LinearLayout>
</LinearLayout>
As you can see, I have three areas in my layout, a fixed left column containing a fragment with buttons the rest of the layout is divided vertically with a fragment managing a textView at the top and a grid of data in the lower section.
I want to use a common layout to place various GridView elements in the "grid_frame" as I press buttons in the "buttons" fragment. Here is the "grid_fragment" layout that I want to use for each GridView fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/grid_fragment_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="80dp"
android:clipToPadding="true"
android:gravity="center"
android:horizontalSpacing="20dp"
android:numColumns="auto_fit"
android:orientation="vertical"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp" >
<!-- Preview: listitem=#android:layout/simple_list_item_2 -->
</GridView>
<TextView
android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="22sp"
android:textStyle="bold"
android:text="#string/no_list_items"/>
</LinearLayout>
This composite layout opens up fine when I start my app. and I set my first fragment in the FrameLayout id "grid_frame" in my initial activity with the following code:
// Execute a transaction to put the categoriesFragment in the grid_view
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.grid_frame, new CategoriesFragment(), "category_fragment");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
This works perfectly fine and I see my buttons on the left, text input box on top and a grid of nicely filled cells to the right of the buttons.
When I click one of the list items in the GridView presented by the dynamic fragment I want to replace the fragment in the "grid_frame" FrameLayout. I do this with the following code in the onItemClick listener method of the "grid_frame" fragment with the following code:
// Execute a transaction to put the categoriesFragment in the grid_view
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.grid_frame, categoryWordsFragment, "category_words_fragment");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
Which looks remarkably similar to the code I used in the activity to set the initial fragment which worked fine.
When I do this my entire screen is replaced with the new fragment layout, which is another GridView with different data. My root layout appears to be totally replaced with the layout that was inflated by the new fragment even though I specify the "grid_frame" FrameLayout as the container view id in the replace method call.
I have tried everything I can find to make my layout stay intact and just change the fragment in the FrameLayout container.
What am I doing wrong please?
Problem solved! It was a very stupid mistake. I had converted my Activity classes to Fragment classes and in this one class I had forgotten to remove the call to setContentView in the class onCreate method. So the fragment was setting a new layout each time I created a new instance