I am adding layouts to my Project and each time I add a layout it also add another layout that comes with the Word "fragment"... can somebody explain me for what is for? I had look over the web and it explain other kind of fragments...
Android Studio, when asked to create an Activity, will create 4 things for you :
An Activity class
a layout file for the Activity class, which will include a FrameLayout serving as the container to place the fragment
a Fragment class (created as an innner class inside your Activity)
a layout file for your fragment (this is the second layout you see in
your project structure), say for example fragment_test.xml
If you look closely, you Activity code will contain something like this :
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_test, container, false);
return rootView;
}
}
My guess it that this was done so it guides developers to use fragments for the screen's actual content rather than placing it inside the Activity's layout itself. The Fragment is designed to be a re-usable component, so if you have several layouts for your activity depending on the screen size/orientation, you can re-use the same fragments, just placing them differently inside your Activity layout, which is an excellent practice.
I hope I clarified things a bit ;)
This is an Android 0.8 question, using the Activity with Fragment template.
So, how would you go about swapping one fragment in for a second fragment? in the same Frame? Perhaps for a button click, for example.
Use case, might be a "connect the dots" questionnaire where the next button goes to the next fragment.
I understand that the answer is FragmentManager and FragmentTransactions.
When I do this from with in a click event,
FragmentManager FM = getFragmentManager();
FragmentTransaction FT = FM.beginTransaction();
FT.replace(R.id.container, new FRAG02());
FT.addToBackStack(null);
FT.commit();
I get an error:
must implement OnFragmentInteractionListener
It would seem that there is a SOP way of replacing fragments that I am not aware of. Seems like a related comment.
Related
So I basically have a button in 'DemosFragment' and when I click it, I want it to open another fragment (SettingsFragment), I understand now that I need an activity to fix this issue, as the button currently has an onClick method using intent/startActivity, so how would I go about creating an activity that just holds my fragment? I know that may sound weird they way I wrote it, I just started Android development, but basically I have a fragment and because I want a fragment to have a button to open another fragment, I figure I need an activity for the fragment I am trying to open, so how do I create that activity and what do I need to put in it? Thanks.
You need an activity with the following code:
public class ShowFragmentActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_fragment);
}
}
You also have to create a layout xml file called activity_show_fragment.xml in your res/layout folder:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.yourFragmentsClassName"
android:id="#+id/fragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
This should work for just displaying your fragment.
To launch the activity, paste this code in your button's onClick method:
Intent i = new Intent(this, ShowFragmentActivity.class);
startActivity(i);
It's always a good decision to look at the official docs: http://developer.android.com/reference/android/app/Fragment.html.
Hope that helps!
Wow! Your question requires a long answer, however is a good practice (and madatory too) that Fragments cannot communicates between each others, but they can be hosted by an Activity; in that case an Activity can manage the communication flow between them (fragments) and can be developed in several ways, Bundle, Intent and the Handler. Have a look to the ufficial Android documentation here:
http://developer.android.com/training/basics/fragments/index.html
The android docs section on building a flexible UI is a good example of how to start/load a Fragment from an Activity. In the example you will see that a FrameLayout in the Activity XML is used a the fragment container. This will be the View in which all of your fragments are displayed.
When you load your fragment with a FragmentTransaction the contents of your fragments layout will be displayed in the container View. In the above referenced example this takes place with SupportFragmentManager a class included with the android support library, for facilitating fragment transactions in earlier version of the operating system. SupportFramgnetManager requires that you extend FramentActivity and not just Activity. If you're not worried about backwards compatibility and are extending activity, not fragment activity, you can simply use getFragmentManager() instead.
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
After the initial add transaction you can switch between fragments using the replace method for your fragment transaction. Replace does exactly what it sounds like, it swaps one fragment for another. To accomplish this from within your firstframgnet use
SecondFragment secondFragment = new SecondFragment();
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, secondFragment).commit();
Notice that from within the fragment I used getActivity(). This allows you to reference the context of the host activity to access the fragment manager. When you are within the activity you do not need to use getactivity because the fragment manager is already accessible from that context.
My older version of an Android app was using 4 different activities (FirstActivity => FourthActivity, with the corresponding xml activity_first => activity_fourth), and the app can switch back and forth between those using Intent. Recently I wanted to change the user interface to use a ViewPagerIndicator. I have implemented 4 fragments like this:
public class FirstFragment extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.activity_first, null);
}
}
The question is, how can I migrate all the business code from FirstActivity to FirstFragment? Do I just need to find the equivalents of onCreate, onDestroy, onStart... and copy/paste the code (adding getActivity(), getView() where appropriate)? Is there any easy way to attach the fragment to an activity to avoid doing so?
The easiest way to do it is to migrate the code you had in your individual activities under onCreate() to onActivityCreated() in the new fragments. You then add the fragments to your activity using a fragment transaction in the onCreate() method of your supporting activity. The android docs give a pretty good walk through of how to do this here, complete with sample code. In case there's some confusion you're going to do the following in your underlying activity:
Get a new FragmentManager
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Create a new instance of your fragment
ExampleFragment fragment = new ExampleFragment();
Add that fragment to your FragmentManager
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
There are a number of different ways to use fragments - like in a ViewPager or ViewSwitcher that require a different implemenation but this sounds like it address what you're trying to do.
this is a though one for me. I have a MainActiviy which extends FragmentAnctivity. There I have 1 FrameLayout and buttons below to change frame's content. I do so by switching show/hide for created fragments which I added to FrameLayout before in OnCreate.
I'm also nesting more fragments in 1 fragment (As I have 1 fragment for 1 type of content and inside of it there is listFragment which is changed to DetailFragment after OnItemClick... again with show/hide approach).
Problem is that in 2 different contents I have 2 different instances of 1 Fragment class, so those 2 instances use 1 same layout file. And although the first of those fragment is hidden and 2nd is shown, when I change some view through 2nd instance then layout of 1st instance is changed and 2nd remains same as before. (Hope it is understandable)
I guess it's totally a mistake in managing and understanding of fragments' lifecycle, so can please someone help me to solve this?
Thanks very much :)
I suppose you get main point of fragments using practices. Your problem is simple. I almost sure you use getActivity().findViewById(...) calls to access views in your Fragment (or nested Fragment whatever). I this case Activity would return you fist view with defined id from whole your views hierarchy.
Solution is pretty simple - you just must avoid getActivity().findViewById(...) construction and get all links to views in onCreateView() callback and use exact this link with all future operations. Than everything will be ok. Here is simple example:
private TextView mDummyText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layout_name, container, false);
initMembersViews(v);
return v;
}
private void initMembersViews(View v) {
mDummyText = (TextView) v.findViewById(R.id.fr_houses_list_text);
}
Hope it would helps you! Good luck!
I'm working on an application and let's say I have 5 different layouts plus a main layout which has links to each layout. In the main layout when the user click to the first button it is suppose to go the related layout by sliding. And It's same for other views.
When the user goes to one of these layouts, the next layout also has a couple of links to other layouts as like a chain. And this chain is moving from layout to the other one by sliding.
I have tried to do this with view flipper but since I have so many different layouts and they have background images and some contents in it, I get out of memory error.
So I'm trying to find a solution in this manner. Any idea how to accomplish this ?
I would recommend you to use Jake Whartons ViewPageIndicator:
Create a Fragment for every of your Layouts and set the layout to your Fragment with the onCreateView() methode inside your fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout, container, false);
}
Now create a FragmentPagerAdapter there sould be a methode called getItem(). Switch the Position and set it to your Fragment:
public Fragment getItem(int position) {
switch(position)
{
case 0:
TestFragment fragment = new TestFragment();
return fragment;
case 1:
TestFragment2 fragment2 = new TestFragment2();
return fragment2;
}
DefaultFragment fragment3 = new DefaultFragment();
return fragment3;
}
Now you should be able to swipe to your Layouts(Fragments) easily
Start a new android.app.Activity hosting each layout and override the transitions between activities using overridePendingTransition(R.anim.animation_leave, R.anim.animation_enter); where *.anim.animation_leave and _enter are neatly already spec'ed out for you in this SO answer.
You can write the overridePendingTransition code immediately after your call to start the 'chained' activity and (if required) the reverse effect can be applied by providing the opposing transitions after calling finish() on the Activity or selecting the 'Up' navigation button press or 'back-button' press.
Having a single activity manage one layout will (in my experience) also benefit code maintainability.
I am trying to understand a bad behaviour in fragments: the onCreateView and onActivityCreated methods are called even the fragment is not 'visible' in the layout.
If you use the code:
TestFragment testFragment = new TestFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentDetail, testFragment, "test");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
replacing the FrameLayout with id fragmentDetail with the fragment and then you rotate the device, the fragments method are still invoked even if the container is not present anymore in the portrait layout. This doesn't happen if you use the 'static' <fragment> tag.
If you use the static fragment, the fragments methods are invoked just when the fragment appears. Is it possible to achieve the same behaviour without using the fragment tag? I need a way to avoid the rendering of the fragment if it is not in the layout.
Thanks
I have found one fix to this. It is slightly different from the suggested Handling orientation changes with Fragments one:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (!fragment.isInLayout() && container == null) return null;
...
}
In this way you can avoid the case when the fragment is statically put into the layout (in that case the container is null but the method isInLayout() returns true.
By the way it is still weird to me this behaviour.
AFAIK, fragments work almost as Activities. They have the same lifecycle. http://developer.android.com/reference/android/app/Fragment.html#Lifecycle So, if you don't have references to them, it won't make them close. They are referenced by the system and live by themselves. So, you should finish them somehow.