how to change fragment's class dynamically - android

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..

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.

FragmentActivity inside a fragment

I am new to android and i have some questions. I created a simple layout with two fragments such as follow:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
I want to divide this layout as follow :
layout_height of fragment1 : 1/3 height
layout_height of fragment2 : 2/3 height
How can do it?
I used below code to show fragment1 :
FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment1, firstfragment);
But I don't know how to show FragmentActivity in fragment2 ?
You can achive this layout like this
<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"
>
<FrameLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2" />
</LinearLayout>
and in java you must call commit in transaction
//to add Fragment1
FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment1, firstfragment).commit();
// to add Fragment2
FragmentTransaction transaction1 =
getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.fragment2, secondfragment).commit;
and you can not put any activity inside Fragments. but you can start another activity from your fragments
To put two elements in some ratio - use LinearLayout then set height of contained views to 0dp and add layoutWeight attributes in desired ratio (for example 1 and 2 in your case)
To instantiate fragments just use code as you written twice. You omitted the transaction.commit(); part. You have to cal this twice - once for every fragment you want to add.
Question about adding FragmentActivity is misleading - you can't put Activity into Fragment, you only can insert Fragment(s) into Activities.

How can I put this fragment on top of the other?

I have this view:
<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:background="#color/DeepSkyBlue"
tools:context=".MainPreviewActivity"
android:weightSum="5">
<fragment
android:name="com.apps.foo.bar.CleanPreviewFragment"
android:id="#+id/clean_preview_fragment"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"/>
<fragment
android:name="com.apps.foo.bar.ProcessedPreviewFragment"
android:id="#+id/processed_preview_fragment"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"/>
<View
android:id="#+id/center_dummy_view"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"/>
<ListView
android:layout_height="0dp"
android:layout_weight="2"
android:layout_width="match_parent"
android:id="#+id/lvImageProcessChoices"/>
</LinearLayout>
I want fragment with id clean_preview_fragment to be replaced with fragment with id processed_preview_fragment.
My app needs to have a camera running in the background so it gets the frames, processes them and displays them in the processed_preview_fragment.
Here is my code:
processedPreviewFragment = (ProcessedPreviewFragment) fragmentManager.findFragmentById(R.id.processed_preview_fragment);
if(getResources().getConfiguration().orientation == getResources().getConfiguration().ORIENTATION_PORTRAIT){
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.clean_preview_fragment, processedPreviewFragment);
fragmentTransaction.commit();
}
That is in my MainActivity, onCreate.
I get this error:
java.lang.IllegalStateException: Can't change container ID of fragment ProcessedPreviewFragment{41b14770 #1 id=0x7f0e0050}: was 2131624016 now 2131624015
You cannot replace a fragment that was declared via XML. If you want to add fragment to container in runtime, you should use FragmentManager to add it. In this case container should be some layout, e.g. FrameLayout.
So, replace your <fragment> tag in XML with <FrameLayout> and add CleanPreviewFragment there in runtime. Then, when you need to replace it, use FragmentTransaction like you do it now. You shouldn't get that exception anymore.

FragmenManager replace makes overlay

I'm using supportlib v4 to reach master-detail flow.
Problem:
New instance of "details" fragment overlays the first one (xml created) instead replace it.
My Activity layout is:
<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="horizontal"
tools:context=".TrackListActivity" >
<fragment
android:id="#+id/fragmentList"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="#+id/fragmentTrack"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackInfoFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
Method called after click:
private void showDetails(long trackId){
View fragmentContainer = getActivity().findViewById(R.id.fragmentTrack);
TrackInfoFragment trackInfoFragment = TrackInfoFragment.newInstance(trackId);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(fragmentContainer.getId(), trackInfoFragment).commit();
}
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.
Which is very last thing on http://developer.android.com/training/basics/fragments/creating.html
Here is solution - just need to change fragment to FrameLayout without loading it at activity creation:
<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="horizontal"
tools:context=".TrackListActivity" >
<fragment
android:id="#+id/fragmentList"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
Check following code it will work.
View fragmentContainer = ClassName.this.findViewById(R.id.fragmentTrack);
TrackInfoFragment fragment = new TrackInfoFragment();
getSupportFragmentManager().beginTransaction()
.replace(fragmentContainer.getId(), fragment).commit();

How to change the "class" attribute of a Fragment from java code

In my android app, I have defined a fragment in my xml layout. The code is below:
<fragment
android:id="#+id/list_fragment"
android:layout_width="220dp"
android:layout_height="fill_parent"
android:layout_marginLeft="62dp"
android:layout_marginTop="20dp"
class="com.example.shantaportfolio.ListFragment" />
But I need to change the class attribute of the fragment from my java code. How can I do it? which method use?
You need to change <fragment/> by <FrameLayout/> in your .xml file
<fragment
android:id="#+id/list_fragment"
android:layout_width="220dp"
android:layout_height="fill_parent"
android:layout_marginLeft="62dp"
android:layout_marginTop="20dp"
/>
and then use java code to add fragment programatically
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ListFragment fragment = new ListFragment();
fragmentTransaction.replace(R.id.list_fragment, fragment);
fragmentTransaction.commit();
you can get more details from
http://developer.android.com/guide/topics/fundamentals/fragments.html
If you just want to replace a Fragment implementation in the layout insert a "container element" into your layout and set the Fragment there:
in the layout:
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp">
</FrameLayout>
In the code:
final FragmentTransaction tx = this.getFragmentManager().beginTransaction();
tx.replace(R.id.fragment_container, aFragment);
tx.commit();
You cannot intercept LayoutInflator instantiating the declared fragment. But You can replace() any fragment in your Activity with another afterwards.
Update:
You can use an Implementation of LayoutInflator.Factory, and use its onCreateView() method to do something different for some particular tags in layout.
You provide this factory implementation to LayoutInflator using setFactory()
You cannot alter Fragments which are declared in XML. Instead, declare a container where a fragment will belong and in the onCreate() method of your activity, attach a Fragment to this container. When you want to swap Fragments, simply use the replace method and specify which fragment you want to swap.Note: containers are usually made with a LinearLayout by arranging them to the specific size. Below is a simple XML layout which provides a layout on the left which is 2/3 the screen size and another on the right which is 1/3
<?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:baselineAligned="false"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/fragment_container_parent"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<LinearLayout
android:id="#+id/fragment_container_child"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

Categories

Resources