I'm just now learning android, and I have an application that has the main activity add a fragment on startup using the fragment manager. The program then switches between two fragments to perform its function using, again, the fragment manager to replace fragments.
I want this app to display the two fragments together when on a large screen. How do I
A) Detect that there is a large screen
and
B) Have the main activity load the two fragments into the single activity if this is the case?
There are layouts for each fragment and a layout for the main activity which is simply a blank framelayout that is filled in with a fragment during the onCreate. Please remember: there are two fragments, and one activity.The activity loads the fragments into its container using the fragment manager.
A) To detect Large Screens you can use this code
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
which will return true if the device is operating on a large screen.
Also check this link
B) You can have two fragments on same activity by adding fragments by code.
Have 2 layouts in you main layout, which will be containers for both the fragments. then add fragment into each of them by code if screen size suits you.
Use this code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="fill_parent">
<RelativeLayout
android:id="#+id/FragmentContainer1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RelativeLayout
android:id="#+id/FragmentContainer2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
And then to add Fragments.
fragmentTransaction.add(R.id.FragmentContainer1, fragment);
fragmentTransaction.add(R.id.FragmentContainer2, fragment);
Check this link for a nice tutorial by Lars Vogel.
How do I detect that there is a large screen ?
Solution -
Let the application detect if there is a large screen.
Define different layout files for different screen sizes.
Ensuring your layout can be adequately resized to fit the screen
Providing appropriate UI layout according to screen configuration
Ensuring the correct layout is applied to the correct screen
Read - Multiple Screen Support and Support Screen training docs.
How do I have the main activity load the two fragments into the single activity
if this is the case?
Solution -
You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. This is essentially useful when you have defined your fragment container at different layouts. You just need to replace with any other fragment in any layout.
When you navigate to the current layout, you have the id of that container to replace it with the fragment you want.
You can also go back to the previous fragment in the backStack with the popBackStack() method. For that you need to add that fragment in the stack using addToBackStack() and then commit() to reflect. This is in reverse order with the current on top.
Description:
Let's we want to use two fragments to handle landscape and portrait
modes of the device.
Next based on number of fragments, create classes which will extend
the Fragment class. The Fragment class has its own callback
functions. You can override any of the functions based on your
requirements.
Corresponding to each fragment, you will need to create layout files
in XML file. These files will have layout for the defined fragments.
Finally modify activity file to define the actual logic of replacing
fragments based on your requirement.
Steps to create two fragments in Activity -
1 You will use Eclipse IDE to create an Android application and name it as MyFragments under a package com.example.myfragments, with blank Activity.
2 Modify main activity file MainActivity.java as shown below in the code. Here we will check orientation of the device and accordingly we will switch between different fragments.
3 Create a two java files PM_Fragment.java and LM_Fragement.java under the package com.example.myfragments to define your fragments and associated methods.
4 Create layouts files res/layout/lm_fragment.xml and res/layout/pm_fragment.xml and define your layouts for both the fragments.
5 Modify the detault content of res/layout/activity_main.xml file to include both the fragments.
6 Define required constants in res/values/strings.xml file
7 Run the application to launch Android emulator and verify the result of the changes done in the aplication.
Read - FragmentTransaction and Android Fragments.
Related
I have an Activity and two Fragment layouts and classes.
All I need to do is that when I change the screen orientation, reorganize the same content differently.
My question is where should I put my code?
Which class Activity class or Fragment class?
If I code in Fragment class, should I put code in both classes, or if I use main Activity, how would I find objects (like TextViews) from each layout?
You put the code where the views are... It's really that simple.
res/layout-land should keep the exact same view IDs.
For example, MainActivity would load both res/layout/activity_main.xml and res/layout-land/activity_main.xml automatically for you depending on orientation.
findViewById will work appropriately if you don't change any ID values
There is a whole documentation page on this. Notice they use retained Fragments, but that is not necessary.
Also Android Studio: Creating landscape layouts
Based on Comments what i have understood so far.
You have an activity and you have two fragments. These two fragments have different layouts and you want to show these layouts based on the orientation of the device.
Well there are two approach for this problem
1) You want to achieve this using fragments
Create an abstract class for Fragment put common functionality in base class and provide different implementation in different Fragment child class
You can refer this
2) Second approach
It can be achieved in a much simpler way without using fragment.
Create a layout-land directory and put the landscape version of your layout XML file in that directory.
See this thread in stackoverflow
Hope it helps.
Edit: source : http://developer.android.com/training/basics/fragments/creating.html last parargraph says :
Note: When you add a fragment to an activity layout by defining the
fragment in the layout XML file, you cannot remove the fragment at
runtime. If you plan to swap your fragments in and out during user
interaction, you must add the fragment to the activity when the
activity first starts, as shown in the next lesson.
Thanks in advance.
You can use fragments in two ways ,
Static Fragments
Here you can define the fragment in whatever the layout file you need. Only thing is, that defined fragment can not be change at the run time. So, re-usability will be issue here, you cant take the advantage of the re-usability of fragments in this case.
Dynamic Fragments
Here you can define a place holder(frame layout etc) on your layout and you can add/replace whatever the fragment you expect at any time while your activity is running. This ensure the re-usability.
Also you can use backStack if back navigation is required.
So, it depend on your requirement.
If the fragments are defined in Xml you won't be able to change them at runtime; in that case I'd suggest using an <include layout="#layout/my_inner_layout"/> tag, that is not only better performance-wise as it is easier to use (you can access the views defined in my_inner_layout.xml using findViewById() method from the host activity).
When creating an new Android Activity, it used to create an xml file in the layouts folder where I would define the UI.Now it creats two files:
1.Layout file
2.Fragment Layout File.
Could someone explain the difference between the two? Also when trying to add items as listviews, buttons...etc. in which file should I add them to be called in my activity file.
Starting with Android 3.0, Activities may now host Fragments which can be used to develop portions of the UI, and be displayed in different configurations depending on screen size, orientation, and other factors. It is highly recommended to use Fragments in modern Android applications, but is not required.
You can create an Activity layout which will hold one or more Fragments, and then place your UI components in the Fragment's layout. The Activity will load the Fragment, and then the Fragment will inflate the layout you wish to present inside it. You can also dynamically add/remove/swap out different Fragments inside the same Activity, depending on what you wish to display to the user.
You can read more about how to use Fragments here: Fragments | Android Developers
You can also choose to ignore the Fragment design principle, and continue to place all of your layouts into the Activity layout file. In that case, you can delete the Fragment layout.
The default structure of new Android projects has changed since a recent update of the adt:
How it is now: There will be a Fragment "PlaceHolderFragment" created which uses the fragments layout. The other layout is the one that the Activity uses.
How it was before: No Fragment was generated after creating a new project, so there was also no fragment layout needed.
==> You have to decide if you actually want to use Fragments now. If so use the fragment layout and learn how to use Fragments in Android. If you decide that you don't need to use Fragments for now, then you can just delete the PlaceHolderFragment code & delete the fragments layout.
In short, before, it was an activity per its layout file, but now one activity could have more layouts, but the second layout file is automatically generated as a fragment to avoid collision while the android studio is matching the resources, similarly two or more activities could share the same fragment too.
We recently converted an app from a multiple activity based one, to one with a single activity with multiple fragments. The activities that became Fragments used to contain fragments themselves, so we use child fragment managers to host the Fragments in the Fragments (these child fragments I should add, are small and there can be 4 or 5 these on the screen at one time).
This has caused a few issues, namely having to create, and keep track of Unique IDs for the Fragment holders. (Which cause headaches when dealing with the Backstack as well as if any are in any sort of AdapterViews).
We're thinking of just rewriting these components to extend some sort of ViewGroup, likely FrameLayout or LinearLayout. We already do that anyway in some cases, but I was wondering if there are any disadvantages to doing it that way? (I must admit, I don't really see the big deal about Fragments... anything you can do with Fragments, you can do by creating a Custom View. Is this wrong?).
This is a bit of a reverse answer, explaining fragment use. In general you can do most things with Activities, but as the SDK supports fragments, many things will become more cumbersome (ViewPager is an example where fragment use is great).
The advantages (of fragments): code encapsulation, reusable chunks of UI.
The disadvantages (of fragments): more code (e.g. FragmentManager, FragmentTransaction).
Your original use of activities was good, it's not a case where I would have switched to fragments.
Let's say I designed a mobile phone app with two activities: ContactList and ContactDetails. So far so good, no reason to use fragments yet. If I wanted to support a larger device, it would behoove me to display both screens side by side. This is where fragments come in handy. In terms of exactly how to structure your activities/fragments, there's some good advice here:
https://developer.android.com/guide/practices/tablets-and-handsets.html#Fragments
Here are the important bits:
Multiple fragments, one activity:
Use one activity regardless of the
device size, but decide at runtime whether to combine fragments in the
layout (to create a multiple-pane design) or swap fragments (to create
a single-pane design).
Or...
Multiple fragments, multiple activities:
On a tablet, place multiple fragments in one activity; on a handset,
use separate activities to host each fragment. For example, when the
tablet design uses two fragments in an activity, use the same activity
for handsets, but supply an alternative layout that includes just the
first fragment. When running on a handset and you need to switch
fragments (such as when the user selects an item), start another
activity that hosts the second fragment.
.
The approach you choose
depends on your design and personal preferences. The first option (one
activity; swapping fragments) requires that you determine the screen
size at runtime and dynamically add each fragment as
appropriate—rather than declare the fragments in your activity's XML
layout—because you cannot remove a fragment from an activity if it's
been declared in the XML layout. When using the first technique, you
might also need to update the action bar each time the fragments
change, depending on what actions or navigation modes are available
for each fragment. In some cases, these factors might not affect your
design, so using one activity and swapping fragments might work well
(especially if your tablet design requires that you add fragments
dynamically anyway). Other times, however, dynamically swapping
fragments for your handset design can make your code more complicated,
because you must manage all the fragment combinations in the
activity's code (rather than use alternative layout resources to
define fragment combinations) and manage the back stack of fragments
yourself (rather than allow the normal activity stack to handle
back-navigation).
Is it possible to have two fragments - one on the left which controls the one on the right, and dock and undock the left fragment such that on docking the one on the left, only the fragment on the right occupies the screen ? If so how?
You can create a horizontal linear layout as your main layout for your activity and within that layout add two linear layouts that will be the place holders for your two fragments ie leftLinLayout and rightLinLayout. When the activity loads add the two fragments dynamically to the two layouts using a FragmentTransaction.
Within the fragments it is possible to get a reference to other fragments since you have method getActivity() then you call the fragment manager and find the fragment you want to manipulate or remove. However this is not desirable. The better solution would be to build a callback interface that the host activity has to implement so that it becomes a listener to your fragment events and then you let the activity add/remove the desired fragments. A good example of this implementation is the newsreader app in the android developer reference http://developer.android.com/training/multiscreen/index.html .