Can I remove a fragment defined in a layout.xml file? - android

Is is possible to use FragmentTransaction and the remove() method to get rid of fragments that are defined in the layout.xml (using the fragment tag) ?
I did not get this to work using the support libraries v4. The fragment stays in place after you commit the FragmentTransaction, after calling remove(). Can anyone tell me if this is by design, a bug or a feature?
It is possible to replace a fragment that is defined in the lyaout.xml, so I find it a bit strange that it should not be possible to remove it?

The native APIs available starting in Honeycomb work the same as those in the support libarary, so you cannot remove an instance of a Fragment which has been declared in your layout XML file.
With FragmentTransactions you manipulate ViewGroups such as LinearLayouts that act as containers to hold the layout of other Fragments. However, when you declare a Fragment in your layout, it doesn't have a container in the same sense because it is permanently part of the View hierarchy, so you can't remove it. That is by design, to support things like navigation Fragments that you'd never remove anyways. :)
One thing that's interesting, and I found it out totally by accident, is that you can add new Fragments into a Fragment that was declared with the tag in your layout; and it acts as a container for other Fragments

Like #david-c-sainte-claire and #martín-marconcini said, you can't use remove() method and FragmentTransaction to remove the fragment that was defined in the XML. That doesn't mean you are out of luck. You can always use setVisibility() method.
findViewById(R.id.fragment_main).setVisibility(View.GONE);

I did not this to work using the support libraries v4. The fragment
stays in place after you commit the FragmentTransaction, after calling
remove(). Can anyone tell me if this is by design, a bug or a feature?
This is by design (or a lack of a feature, not definitely a feature if you ask me :P). So as long as you are using the support libraries, you can't achieve this.

Related

ListActivity with ActionBar support v7

My main Activity extends ListActivity, and now I have to implement an ActionBar with support for older versions.
I have readed about the ways to do this, and I decided to try this way:
I downloaded the source code of ListActivity, I modified few things, and now I need to implement here the ActionBar, so I'm trying to extend this Activity to ActionbarActivity. This way, I would have a custom ActionBarListActivity, and I could extend my Activity to this custom class, have then the functionality of the ListActivity and the ActionBar.
These are the steps I've done:
Add the support v7 library to my project
Set as aplications theme the #Style/Theme.AppCompat
But when I'm trying to extend the activity to ActionBarActivity, doesn't let me do this, it says "ActionbarActivity cannot be resolved to a type" and suggest to change it for 'ActionBar'(android.app). I know I have to import the "import android.support.v7.app.ActionBarActivity" but it doesn't let me do this.
So, what is going wrong here?
A simpler approach (to downloading source, etc.) is to break out the list into a Fragment and just include the Fragment in the Activity. I'll outline the steps to get there:-
Split out the list into it's own layout XML. So you will end up with 2 XML's - one for the Activity 'container' which will be pretty simple - (see step 2), and one for the new Fragment layout which will be your overall layout for the list, but most importantly will include a <ListView> element).
Include a <FrameLayout> placeholder in your activity's layout XML (to be the container for the fragment). It will be nested inside the top level layout (a <RelativeLayout> would do as the top level). Give the placeholder an id like myFragmentHolder.
Create a new Fragment class (extend ListFragment) called say, MyListFragment.
Move all of your list code (such as ArrayAdapter code etc.) into the new fragment class
Your Activity code is now really just a shell to contain the fragment and to manage the ActionBar. To support the list fragment all it needs in onCreate() is the call to setContentView() and to replace the fragment:- getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_ENTER_MASK).replace(R.id.myFragmentHolder, new MyListFragment(), "MY_LIST").commit();. ("MY_LIST" is an arbitary tag name you use to identify the fragment. It can be anything -read the docs for more info).
Your Activity should still extend ActionBarActivity.
Now you have a nice separation of concerns. The Activity manages the ActionBar and the Fragment manages the List.
It does not sound like you imported the library right especially.
in eclipse you need to right click on the project, go to Properties, select Android in the list then Add to add the library
follow this tutorial in the docs
http://developer.android.com/tools/support-library/setup.html
Update:
Try this:
Import support library as a project from "sdk/extras/android/support/v7/appcompat".
Reference library in your project (for Eclipse, "Properties - Android - Add").
Build projects (for Eclipse,"Projects - Build All"). Make sure, you have "android.support.v7.appcompat"in your main project gen folder.
If it still doesn't solve your problem, restart eclipse.
then clean and rebuild project
If the problem persists, remove the support library from you computer and redownload it and follow above mentioned steps.
Thank you Nebu for your great explanation.
Theo, for simplicity, you might check out this tutorial on how to change a ListActivity to an ActionBarActivity by using a ListView object. (http://www.opensourcealternative.org/tutorials/android-tutorials/simple-android-listview-without-listactivity/)
However, Theo, I'll try to clarify Nebu's instructions with a little more details in order to try and answer your questions about his instructions.
Theo, as far as I understand, this is what Nebu is saying needs to be done.
In your original activity's XML for the listactivity, you had a FrameLayout.
You're going to copy the FrameLayout element to your new XML for your ListFragment, and the FrameLayout will be the root element in that new XML file.
In the original activity's XML file, replace the original FrameLayout element with a simple declaration of a FrameLayout element and an ID, just the start and end tags of the XML element without any child elements. This will be used to populate the FrameLayout with the one in your ListFragment at runtime.
The R.id.myFragmentHolder is the ID of the FragmentLayout placeholder in your original activity's XML file.
The "new MyListFragment()" call is calling the constructor of your new ListFragment class.
"MyList" can be any string, I would personally make it more descriptive of the list I was using, but it doesn't matter. Search Google for android fragment Tags to learn more about Tags.
When you extend ActionBarActivity, you will get errors unless you import android.support.v7.app.actionbaractivity in your actionbaractivity class that is replacing your original ListActivity class.
if I missed anything or if anything is not clear, please let me know.

Navigation Drawer implies nested fragments?

I created an application with a navigation drawer navigating following the android documentation tutorial. Now the main parts of my application are Fragment but the problem is I have to use dynamic fragments in one of them.
I saw the nested fragments were supported since android 4.2, but I need to use my app on older version.
What can I do ?
I'm thinking of using a FrameLayout of fixed fragments and to set them visible or gone depending of what I need, but it seems a little ugly...
What do you think ?
Thanks for your answers
Edit :
my question is not clear but what I want to know is :
can I use the navigationdrawer with activities instead of fragments ?
is the solution I'm thinking about realy ugly ?
how can I use the nested fragment system for older version ?
In the end I used the nested fragment system using the Android Support Library (thanks Nobu Games)
Thanks for your comments

Add Fragments in xml or programmatically?

I am wondering is there any reason to do one over the other. I have been adding fragments via xml and using show/hide. I wanted to learn about replace/add/remove so I tried to add them programmatically. This has led to problems fragment remove issue and just seems less straight forward to me.
It also seems easy to place them via xml, whilst I'm still not sure how to programatically (as you don't have a reference to the fragment in the xml of the view that youa re adding it to?). Is there any reason for me to add fragments programmatically?
Fragments added in XML cannot be replaced or removed, other than that major limitation choose whichever method is easiest for you.

Hosting widgets inside fragments

Is it possible? supported?
I want to make an app that hosts widgets in fragments, I know how to do it on activity but don't know if it works with fragments.
Im sure you mean AppWidgets, so take a look at this
https://github.com/DagW/FragmentHomescreen
It contains a complete example project for adding widgets to fragments in a viewpager.
It also contains code for adding appwidgets programatically.

My first ever Android code with Fragment

As an exercise, I am trying to rewrite the following google tutorial with Fragment class. The original tutorial implements tabs by using the old TabActivity class and TabHost/TabWidget annotation.
Tab Layout Google Tutorial
I have converted all Activity class with Fragment. I couldn't make my new code to work. I think I am stuck.I could not find any 'complete' Tab sample code using Fragment class.
Here are my questions
1. Should I define in the res/layout/main.xml or calling Actionbar.addTab(...) in my entry class, or both?
2. What would be complete res/layout/main.xml looks like? What would be the root element (i.e. LinearLayout, FrameLayout...etc)?
3. Any additional info would be greatly appreciated.
Check out this example from the compatibility library demos: FragmentTabs.java
and the corresponding layout: fragment_tabs.xml
Really, though, I wouldn't start with Tabs if you're trying out Fragments for the first time. Tabs in Android are a little bit of a mess. The above example (from Google itself) uses a hack just to get things working. Tabs just add a layer of unnecessary confusion when you're just learning.
Here's a more straightforward starting-out Fragments example/tutorial: http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html
(Just make sure to replace things like getFragmentManager() with getSupportFragmentManager() if you're using the compatibility library.)

Categories

Resources