Is there another way in which we can add a fragment? - android

I know of this way to add a fragment:
MyFragment myFragment = MyFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragmentContainer, myFragment );
ft.commit();

There are two ways to add a fragment to an activity: dynamically using Java and statically using XML.
You are already using dynamic way of adding fragment , below is statically using XML.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:name="com.example.app.myfragment"
android:id="#+id/myfragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Related

Not able to understand Fragment replace, role of FrameLayout and where does it fall in place

In one of my fragment I have the below layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/email_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
android:src="#drawable/banner_dashboard" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical">
<include layout="#layout/settings_nested" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
Now the following:
<include layout="#layout/settings_nested" />
Consists of some buttons, on click of one such button I want to replace the framelayout with new contents - new fragment which has a different layout. Here is how I do it:
Fragment fragment = null;
fragment = new FragmentEmails();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.email_container, fragment);
fragmentTransaction.commit();
Now I can see the optionsMenu change when I click the button (As I have defined a different menu file for this new Fragment) However the contents remain the same. Advice any? I think I am doing something wrong the way I am defining the framlayout as the parent of my views, but what exactly, beats me.
According to my Thoughts and Views, You should Do as below
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/email_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
This is the Parent Layout of all fragment and email_container will be used for the transactions of other fragments.
then Create another layout that consists of the inner elements that i have erased.
on startup what you want to display , Change this email_container inneer elements with another fragment like
Fragment fragmentStartPage = null;
fragmentStartPage = new FragmentEmails();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.email_container, fragmentStartPage);
fragmentTransaction.commit();
then change it with another fragment by replacing the fragmentStartPage with another fragment.

Creating a Multi-pane layout using android actionbar and navigation drawer

I'm currently creating an app which can handle different screen support and multi-pane view using fragments. Now I used the default navigation drawer and actionbar using android studio and created two fragments to test for this and layouts for portrait: fragment_1 and fragment_2 which just replaces the container on the MainActivity. But now the problem is how can I implement the fragment_1 and fragment_2 in 1 layout? I Tried to research on the multi-pane development on this link but I think to properly implement it I need to use an ActivityFragment but in this case I am limited on using just Fragments which is why I'm lost on what to do. Here's the code so far:
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
switch (position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentMain.newInstance(position + 1))
.commit();
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentAbout.newInstance(position + 1))
.commit();
break;
/*create the other cases here for navigation*/
}
}
fragment_main.xml (the 1st fragment)
<RelativeLayout 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="com.kahel.main.MainActivity$PlaceholderFragment">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
fragment_about.xml (2nd fragment)
<RelativeLayout 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="com.kahel.main.MainActivity$PlaceholderFragment">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
fragment_main.xml (landscape)
<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"
tools:context="com.kahel.main.MainActivity$PlaceholderFragment"
android:orientation="horizontal"
android:weightSum="1">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="#dimen/land_scoop_feed"
android:layout_height="match_parent">
<ListView
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
When I tried to change the layout it just force close my app. :/
Please let me know what to do or what to search for. Thanks! :)
Well, I ran into the exact same problem and after doing a lot of research I was surprised on the lack of documentation for this, in my opinion, common situation. But, after trying a few things I came up with a solution.
My first approach was to replace the Navigation Drawer container with a "root fragment" that at the same time would have two layouts available containing the fragments that I want. The problem was that nested fragments declared on the layout are not permitted.
To overcome this other issue, in my "final layouts" I replaced the Fragment definitions for FrameLayouts and then load the fragments programatically on the "root fragment".
To summarize: You have your Navigation Drawer and upon clicking what you want, you replace your fragment container with a "root fragment". This "Root fragment" has two layouts: a default one and another for landscape. These layouts contain FrameLayout elements arranged as we want that upon initialization are replaced by our "final fragments".
I doubt that this is the best way to achieve the goal of having Multi-pane layouts with a Navigation Drawer but is what I was able to do that best suited my needs. I welcome any suggestions!.
I illustrate the solution with some code.
MainActivity.java (The one with the navigation drawer)
...
void drawerOptionSelected(String option) {
if(option.equals(XXXX)) {
Fragment fragment = new RootFragment();
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, fragment);
transaction.commit();
drawerList.setItemChecked(menuOptions.indexOf(option), true);
drawerLayout.closeDrawer(drawerList);
}
}
...
root_fragment_layout.xml (Default)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/entries_list_single"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="match_parent" />
root_fragment_layout.xml (Landscape)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:baselineAligned="false"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout android:id="#+id/entries_list"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<FrameLayout android:id="#+id/entries_post"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
</LinearLayout>
RootFragment.java
public class RootFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.root_fragment_layout);
if(savedInstanceState != null) { //Fragments already loaded, avoid replacing them again
return;
}
ListFragment listFragment = new ListFragment();
final FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); //IMPORTANT! Use child fragment manager
if (findViewById(R.id.entries_list_single) == null) { //We are loading the landscape layout
PostFragment postFragment = new PostFragment();
transaction.replace(R.id.entries_list, listFragment);
transaction.replace(R.id.entries_post, postFragment);
transaction.commit();
} else { //We are loading the default layout
transaction.replace(R.id.entries_list_single, listFragment);
transaction.commit();
}
}
}

How can I add more fragments of the same class to a Layout?

I have the following code:
FragmentA myFragment = new FragmentA();
transaction.add(R.id.my_fragment_container, myFragment);
myFragment = new FragmentA();
transaction.add(R.id.my_fragment_container, myFragment);
transaction.commit();
So what I want that happens is, that this will create 2 fragments.
One of the both should be placed under the other one.
My layout looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:id="#+id/my_fragment_container"/>
</LinearLayout>
So what do I have to do that 2 Fragments were added and one of them is under the other one?
regards simon
1) Make the following code a separate XML layout file:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
2) Inflate it using code and grab the id of the inflated layout.
3) Programmatically add the inflated layout to the layout with id=my_fragment_container.
4) Add the fragment to the FragmentManager with the inflated layout id.
FragmentA myFragment = new FragmentA();
transaction.add(layout_id, myFragment);
I believe that this should work, cheers.

How to display one activity inside another in Android?

I have one activity and want to display another inside it. Here's my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>
How can I display an Activity in inner LinearLayout on button click?
Use one layout for several activities
Layout instance is inflated for each activity using a setContentView method, usually in onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_common_layout);
}
So there's no problem to use the same XML layout for different activities.
Display one activity inside another
You can use a Fragment API to complete the task. See full details in developer's guide.
Declare a layout like that and Android will create fragments for you:
<?xml version="1.0" encoding="utf-8"?>
<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:name="com.example.MyFragment"
android:id="#+id/my_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
Then create a MyFragment class and load it when appropriate.
Create fragments yourself. Do not define the Fragment in XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/my_parent_layout">
</LinearLayout>
After your parent Activity is created you can add a new Fragment in this way:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.my_parent_layout, fragment);
fragmentTransaction.commit();
Here MyFragment is defined like this:
public class MyFragment extends Fragment {
...
}
If you're targeting below Android 3.0, consider using support package for that.

how to change fragment's class dynamically

Hi I have a linearLayout containing two fragments and I add tabs with code to this layout. What I want is when I click tab1 it is ok to fragment fill itself from indicated class, but in tab2 I want to change this class to another class. Thank you
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frags">
<fragment class="com.tugce.MitsActionBar.DoktorlarFragment"
android:id="#+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="#dimen/titles_size"
android:layout_height="match_parent" />
<fragment class="com.tugce.MitsActionBar.ContentFragment"
android:id="#+id/frag_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Change <fragment/> in xml layout to <FrameLayout/>
<FrameLayout
android:id="#+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="#dimen/titles_size"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/frag_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and add fragments programmatically:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.replace(R.id.frag_content, fragment);
fragmentTransaction.commit();
But at first read this.
Shortest version of calling a fragment
getFragmentManager().beginTransaction().replace(R.id.splash_container, new ExampleFragment()).addToBackStack(null).commit();
addToBackStack(null) is optional if you want to save the fragment on stack or not..

Categories

Resources