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.
Related
Background
In my app I have a lot of fragments that share the same static overlay. Each fragment can be resized dynamically (i.e. its weight may change) so I want the size of my overlay to be in sync with it. Therefore it makes sense to either make them siblings or, as it occurred to me, put one inside another. The first approach works fine but it implies introducing one extra ViewGroup which seems redundant (or does it not?). The latter is the one I'm having problems with.
Problem
Consider these two layouts.
Container R.id.container is where I put my fragment in runtime with FragmentManager.
Fragment R.id.overlay is my overlay.
The difference is which one is the parent.
Layout A.
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.OverlayFragment"
android:id="#+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Layout B.
<fragment class="com.example.OverlayFragment"
android:id="#+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</fragment>
In both cases my overlay ends up below container (by z-axis). That is, container keeps overlapping it regardless of its role in hierarchy.
What are the rules for defining views's z-order in situations like this? Is it just the order of their initialization? I couldn't google it out.
Thanks.
From documentation:
When the system creates this activity layout, it instantiates each
fragment specified in the layout and calls the onCreateView() method
for each one, to retrieve each fragment's layout. The system inserts
the View returned by the fragment directly in place of the
element.
So I think you should use something like this:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<fragment class="com.example.OverlayFragment"
android:id="#+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
My app consists of multiple activities, they all have a common layout in the sense that they are drawer layout, have a tool bar, but they have different main content. Specifically, their complete layouts are as follows
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/relative_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/action_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
/>
.......main content, this is different for each activity..........
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Since the shared components are defined at "parent level", I'm not sure how to structure these layouts so that the generic layout is only defined once. Is it possible to achieve that? Thanks.
Two options:
1. ViewStub
Define the main layout with a ViewStub where you will have different sub-layouts.
A ViewStub is an invisible, zero-sized View that can be used to lazily
inflate layout resources at runtime. When a ViewStub is made visible,
or when inflate() is invoked, the layout resource is inflated. The
ViewStub then replaces itself in its parent with the inflated View or
Views.
In each Activity you set the same layout and then inflate the specific sub-layout onto the ViewStub.
2. Fragments
If you want to avoid having massive quantities of code on a single Activity you might want to think about using Fragments.
Some other topics to guide you:
How to use View Stub in android
Loading Views On Demand
Yes it is possible by using Fragment. For this structure first you need to define a FrameLayout in your activity_main.xml . This framelayout will be replaced by the contents of the fragments over the time.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
</LinearLayout>
<FrameLayout
android:id="#+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
<fragment
android:id="#+id/fragment_navigation_drawer"
android:name="com.safallwa.zahan.oreader.FragmentDrawer"
android:layout_width="#dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
Then you can create your layouts as you want and classes as those extends Fragment . Set these new layouts as contentView of Fragment classes. Now these fragments can replace that FrameLayout of activity_main. Suppose we have a Framgent class name First_Fragment.Java then we can show that fragment by replacing activity_main framelayout by below code
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);//container_body is the id of the framelayout
fragmentTransaction.commit();
For full featured example with navigation drawer also we can follow below link
http://www.codedisect.com/?p=134
I have tabs that contains Fragment and i want to provide the swipe gesture to move right and left. I'm using it inside of Fragment and inside of activity. I use ViewPager inside of FragmentTabHost both from support.v4 package (need to work on >=API 10). The problem is that the pager starts showing the content from the top of layout and tabhost is showing the tabs first and then the content. Of course i want the second behavior. So what i see is the content twice, one with tabs and one without. Here is my layout xml file. Notice that i have also some other views above the tabhost (#+id/relative_header) so action bar tabs don't fit in this case. I've already try to move pager into realtabcontent or above it with no luck.
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#+id/relative_header" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+android:id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
I'm not sure but I assume that one of them is incompatible with the other, but i don't know which compination should use to provide swipe gesture between fragments tabs. Any idea about what I'm doing wrong?
Well, i'm writing this answer for anyone will have the same question in future. I misunderstood the role of each layout. ViewPager and TabHost doing more or less the same thing. To enable the swipe gesture i should have used ViewPager. To add tabs to this, i used the library PagerSlidingTabStrip , also on Feb. 14 2014 seems that android team released a native layout for this: PagerSlidingTabStrip . The tricky point was that tabhost has content and tab in the same layout but it cannot provide the swipe gesture.
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();
It's is possible to "stack" fragments on top of each other?
Just tried to do this without really thinking about it and everything got kinda crazy.
I can (and probably should) create a ViewGroup instead if it's not possible, but I was just wondering.
Yes, it's possible. E.g. by wrapping them inside a FrameLayout like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.package.FragmentOne"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<fragment android:name="com.package.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
The z-index depends on the order of the children within the layout. In this example FragmentTwo is above FragmentOne because it's the second child.