Trying to create Facebook / Gmail style Sliding Navigation Drawer. All I want is to create separate Fragments in XML, and show them when user clicks one of the list items from Drawer Menu. Each Fragment hooked up to one item in the list.
NavigationDrawer is great example app to start with, but it only demos loading fragment dynamically. I want even simpler, just loading those statically. How should (Code snippet please) I be instantiating Fragments within my activity on List menu item click? How would MainActivity XML look like ?
Please read the docs http://developer.android.com/guide/components/fragments.html
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">
<FrameLayout
android:id="+#id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Java
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Related
When i am adding multiple fragments to a FragmentTransaction and commiting after that only last fragment is added.
getFragmentManager().beginTransaction().add(R.id.main_container,PropertyListFragment.newInstance()).addToBackStack(null)
.add(R.id.main_container, BlankFragment.newInstance("dfghj","fghj")).addToBackStack(null)
.add(R.id.main_container,PropertyListFragment.newInstance()).addToBackStack(null)
.add(R.id.main_container, BlankFragment.newInstance("dfghj","fghj")).addToBackStack(null)
.commit();
Backstack count is also 1.
You can't use fragment in this way you need to use just one fragment per container.
check this:
How do I properly add multiple fragments to a fragment transition?
Above answer is right.
You can't use fragment in this way you need to use just one fragment per container but I gave you a little help here.
You need to define at the XML FrameLayout for each Fragment something like this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<FrameLayout
android:id="#+id/fragment_2"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
And in the Fragment you need to define like this.
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
ListFragment listFragment = new ListFragment();
WebFragment webFragment = new WebFragment();
trans.add(R.id.fragment_1, listFragment, "list_fragment");
trans.add(R.id.fragment_2, webFragment, "web_fragment");
trans.commit();
Interesting issue here guys, which I hope somebody can shed some light on.
I currently have a Maps v2 fragment with a Sliding Drawer (deprecated - I know) on the same screen. Once the user is finished with their tasks, they can pull the sliding draw up and click "finish". This makes use of SupportFragmentManager and I basically end up replacing the contents of the screen with a brand new fragment.
However, the user is still able to click content on the Sliding Drawer even though it has been replaced with the new fragment. Any hints?
Below is the skeletal structure of the responsible code:
activity_map.xml
<RelativeLayout android:id="#+id/activity_map">
<LinearLayout>
<include layout="#layout/toolbar"/>
<fragment android:id="#+id/fragment_map"
android:name="com.foo.fragment.MapFragment" />
</LinearLayout>
<SlidingDrawer>
...
</SlidingDrawer>
</RelativeLayout>
MapActivity.java
...
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_map, newFragment, TAG);
transaction.addToBackStack(null);
transaction.commit();
You should try to do like this
activity_map.xml
<FrameLayout
android:id="#+id/container>
</FrameLayout>
fragment_map.xml
<RelativeLayout android:id="#+id/activity_map">
<LinearLayout>
<include layout="#layout/toolbar"/>
<fragment android:id="#+id/fragment_map"
android:name="com.foo.fragment.MapFragment" />
</LinearLayout>
<SlidingDrawer>
...
</SlidingDrawer>
</RelativeLayout>
Now inside your activity you should first start a new fragment (lets say AMapFragment) having layout fragment_map inside FrameLayout (activity_map.xml). Please note now the below code will be part of your fragment (AMapFragment)
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_map, newFragment, TAG);
transaction.addToBackStack(null);
transaction.commit();
And change this line transaction.replace(R.id.activity_map, newFragment, TAG); to transaction.replace(R.id.container, newFragment, TAG);
The simplest and most elegant solution in this case was to set clickable="true" on my new fragment in its static xml layout file.
The next step was to manually associate listeners to the new buttons and text edits on this fragment.
Works like a charm!
I'm pretty new to Android and wanted some help. My app has two tabs (as fragments) in a ViewPager. One of the tabs shows a list of items. On clicking on an item, the app should display the details of the item.
Now how do I this? Do I add the details in a third fragment? If so, how should I add the fragment? I do not want the details fragment to come as a tab inside ViewPager.
I tried adding the details fragment as a separate fragment to the ViewPager. On clicking an item, the fragment is being called (the log statements inside are displayed in console). However, I just get a blank screen.
This is my activity.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
This is the xml for the details fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="600dp"
android:layout_height="700dp"
android:background="#FFFFFF"
android:orientation="vertical" >
...
</LinearLayout>
This is how I'm currently adding the details fragment from the Activity:
DetailsFragment details = new DetailsFragment();
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.pager, details);
transaction.addToBackStack(null);
transaction.commit();
Thanks in advance.
You should open a new activity to display the details. This new activity will simply be a container for your DetailsFragment.
You need to pass the details to display to the Activity in its Intent, then the Activity will pass the details to the Fragment using the arguments Bundle (Fragment.setArguments()). Most of the time, this will be a simple object implementing Parcelable.
I am facing the following issue in my app. I want to add multiple fragments into a vertical LinearLayout in a certain order.
Here is my layout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
And here is the code I use to add the fragments.
Fragment fragment1 = MyFragment.newInstance(param1);
Fragment fragment2 = MyFragment.newInstance(param2);
FragmentManager fm = getSupportFragmentmanager();
fm.beginTransaction().add(R.id.content, fragment1, "fragment1").commit();
fm.beginTransaction().add(R.id.content, fragment2, "fragment2").commit();
I use one transaction each time so I guarantee that they are placed in that order on screen.
My problem is that when the orientation changes and the Activity is re-created there is no way I can be sure that they will appear on screen in the same order.
Has someone experienced this too? How can I solve the problem? Having two layouts inside the LinearLayout with an specific id for each of the fragments will not help, because the number of fragments I have to add is undetermined (I just used the number 2 for the example)
If there's an indefinite amount of Fragments to add, better use a ViewPager with a FragmentStatePagerAdapter or FragmentPagerAdapter. There you can add inifinite numbers of Fragments in a clean way and don't have to worry about a huge list of Fragments using a large amount of memory.
If you want to stay with your ScrollView approach, you can use FragmentManager.executePendingTransactions() to ensure, that the transaction is completed, before the other:
FragmentManager fm = getSupportFragmentmanager();
fm.beginTransaction().add(R.id.content, fragment1, "fragment1").commit();
fm.executePendingTransactions();
fm.beginTransaction().add(R.id.content, fragment2, "fragment2").commit();
fm.executePendingTransactions();
// etc.
Good day, trying to clarify this: if i have this layout for a portrait layout
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
android:id="#+id/configFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.settingsFragment">
</fragment>
and this for landscape(mainly for tablets), main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
android:id="#+id/configFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.SettingsFragment" ></fragment>
<fragment
android:id="#+id/detailFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.Example.DetailFragment" >
<!-- Preview: layout=#layout/details -->
</fragment>
</LinearLayout>
now within my SettingFragment, i implement a button to go to the DetailFragment:
DetailFragment fragment = (DetailFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.detailFragment_id);
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
if (fragment != null && fragment.isInLayout()) {
DetailFragment detailfragment = new WallpaperFragment();
fragmentTransaction.add(R.id.detailFragment_id, detailfragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else{
Intent intent = new Intent(getActivity().getApplicationContext(),DetailActivity.class);
startActivity(intent);
}
Am i now implementing a dynamic fragment or am i still using static fragment?.. or do i only use dynamic fragment when i use a viewgroup like FrameLayout in place of the fragment tag element?
Idea is to have a single pane for phones and multi-pane for tablets.I know its a bad idea to mix static and dynamic fragments, but its kind of confusing. Thank you.
You know, I might be wrong here (so feel free to correct me) but it looks like you're using both static AND dynamic fragments. In your XML layouts you've added the fragments then you are re-instancing them via a fragment transaction in your activity. Alternatively, if you had declared a container (FrameLayout for instance) instead of a fragment in your XML you would have to use a FragmentTransaction to add the fragment at run time.
In your example you are just stepping on the fragment that you all ready have. Basically, the OS sees your fragment in the XML when inflating (I think that's when it calls the fragment code?) and executes the code associated with it via the tag in the fragment. Your app then adds that same fragment over the top of itself. A simple way to show this is to add a LogCat call in your Fragment class's onCreateView method. If you see it more than once, then your stepping on the previous fragment with the same fragment (which I'm 99% sure you are). Hope this helps to answer your question!
Static fragments are defined in the layout and are not generally added or removed at runtime. They are referenced by their id in your code. They are generally put as a child element of a layout like below. Once they are defined here, android will know to make a fragment, that's all you have to do.
<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:orientation="vertical"
android:weightSum="1">
<fragment
android:id="#+id/fooFragment"
android:name="com.example.myapplication.TestFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Dynamic fragments are defined in your code and can be manipulated, added, removed, etc during runtime. They look like this:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.your_placeholder, new TestFragment());
ft.commit();