How to add another fragment on the existing fragment? - android

I am trying to create tab layout with fragments. When i add another fragment on item click it should show another fragment above it. I am unable to get the goal. Fragment just goes above the existing one but both the fragments content are visible. Please don't throw the link towards any developer page for explanation.
Here is my code
home_activity.xml
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.tabsfragment.School_Fragment" >
</fragment>
<fragment
android:id="#+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.tabsfragment.Sports_Fragment" >
</fragment>
</FrameLayout>
</LinearLayout>
</TabHost>
Home_Activity.java
public class Home_Activity extends FragmentActivity {
TabHost mHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity);
mHost = (TabHost) findViewById(android.R.id.tabhost);
mHost.setup();
TabSpec schoolSpec = mHost.newTabSpec("School").setIndicator("School")
.setContent(R.id.tab1);
mHost.addTab(schoolSpec);
TabSpec sportSpec = mHost.newTabSpec("Sports").setIndicator("Sportss")
.setContent(R.id.tab2);
mHost.addTab(sportSpec);
mHost.setCurrentTab(1);
}
entertainment.xml
<FrameLayout
android:id="#+id/frameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</FrameLayout>
I am adding another fragment on list_item_click inside Sports_Fragment
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
FragmentTransaction ft = getFragmentManager().beginTransaction();
Entertainment_Fragment enFragment = new Entertainment_Fragment();
ft.replace(android.R.id.tabcontent, enFragment);
ft.commit();
}
Here is the snapshot :
Any ideas/help with explanation would be highly appreciated.
Thanks!!

First of all, I think it's worth mentioning...
"You cannot replace a fragment defined statically in the layout file. You can only replace fragments that you added dynamically via a FragmentTransaction"
Please see
Android: can't replace one fragment with another
How can I show a new Fragment within a single tab?
Here's the solution.
In home_activity.xml, you should leave your tabcontent empty.
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
Your Home_Activity
private FragmentTabHost mHost;
public void changeFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
EntertainmentFragment enFragment = new EntertainmentFragment();
ft.replace(R.id.tabcontent, enFragment);
ft.commit();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
mHost.addTab(mHost.newTabSpec("School")
.setIndicator("School"), SchoolFragment.class, null);
mHost.addTab(mHost.newTabSpec("Sport")
.setIndicator("Sport"), SportsFragment.class, null);
}
In your onIemClick (Sports_Fragment), add this
MainActivity mainAct = (MainActivity)getActivity();
mainAct.changeFragment();
My full project, which is based on your code, is here.
I haven't had a chance to really check why TabHost doesn't work when I tested your code.
But FragmentTabHost works fine for me.
Edit: To fix the overlap problem, you can set OnTabChangeListener:
mHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
if (tabId.equalsIgnoreCase("School")) {
Log.v(TAG, "school");
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
schoolFrag = new SchoolFragment();
ft.replace(R.id.tabcontent, schoolFrag);
ft.commit();
}
if (tabId.equalsIgnoreCase("Sport")) {
Log.v(TAG, "Sport");
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
SportsFragment sportFrag = new SportsFragment();
ft.replace(R.id.tabcontent, sportFrag);
ft.commit();
}
}
});
About the backpress, you can try
ft.addToBackStack(null);

Related

Android - Hide/Show Fragment showing the wrong fragment

In the first time that I change the visibility of the fragments in my app, the fragment showed isn`t the fragment that I set to show.
My layout:
<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"
tools:context=".MainActivity" >
<fragment
android:id="#+id/act_main_frag_top_bar"
class="br.com.myapp.fragments.TopBarFragment"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<fragment
android:id="#+id/act_main_frag_toolbar"
class="br.com.myapp.fragments.ToolbarFragment"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<!-- Tabs -->
<fragment
android:id="#+id/act_main_frag_twitter"
class="br.com.myapp.fragments.TwitterFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="gone"/>
<fragment
android:id="#+id/act_main_frag_facebook"
class="br.com.myapp.fragments.FacebookFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="gone"/>
<fragment
android:id="#+id/act_main_frag_tv_show"
class="br.com.myapp.fragments.TVShowFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="gone"/>
<fragment
android:id="#+id/act_main_frag_info"
class="br.com.bluepen.mixtv.fragments.InfoFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="gone"/>
<fragment
android:id="#+id/act_main_frag_streaming"
class="br.com.myapp.fragments.StreamingFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="gone"/>
</LinearLayout>
And myActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager = getSupportFragmentManager();
mStreamingFrag = (StreamingFragment) manager.findFragmentById(R.id.act_main_frag_streaming);
mFacebookFrag = (FacebookFragment) manager.findFragmentById(R.id.act_main_frag_facebook);
mTwitterFrag = (TwitterFragment) manager.findFragmentById(R.id.act_main_frag_twitter);
mTVShowFrag = (TVShowFragment) manager.findFragmentById(R.id.act_main_frag_tv_show);
mInfoFrag = (InfoFragment) manager.findFragmentById(R.id.act_main_frag_info);
mToolbar = (ToolbarFragment) manager.findFragmentById(R.id.act_main_frag_toolbar);
mToolbar.setListener(this);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.show(mStreamingFrag);
transaction.commit();
}
After the onCreate, the fragment getting showed is the TwitterFragment, and not the StreamingFragment that I set to show in the final of the onCreate method.
I find the problem, I changed to hide all the fragments in the onCreate. Aparentelly the android:visibility="gone" in the xml didn`t do this.
Here is the code of the onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
mStreamingFrag = (StreamingFragment) manager.findFragmentById(R.id.act_main_frag_streaming);
transaction.show(mStreamingFrag);
mFacebookFrag = (FacebookFragment) manager.findFragmentById(R.id.act_main_frag_facebook);
transaction.hide(mFacebookFrag);
mTwitterFrag = (TwitterFragment) manager.findFragmentById(R.id.act_main_frag_twitter);
transaction.hide(mTwitterFrag);
mTVShowFrag = (TVShowFragment) manager.findFragmentById(R.id.act_main_frag_tv_show);
transaction.hide(mTVShowFrag);
mInfoFrag = (InfoFragment) manager.findFragmentById(R.id.act_main_frag_info);
transaction.hide(mInfoFrag);
transaction.commit();
}
I don`t know if I can set the fragment to hide in the XML.
I had the same issue with 2 buttons (button1 and button2), when i had to hide the first button , the 2nd was hiding and the first was doing nothing... Everything i've done was CTRL+C the xml and CTRL+V back... Hope it works...

Replacing Fragment : Didn't work

I have a Button in Fragment. If Button is clicked it has to replace the Fragment with another Fragment. The Fragments in activity_main.xml is created statically.
<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:background="#efefef"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3" >
<Button
android:id="#+id/bHome"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#000000"
android:padding="3dp"
android:text="Home"
android:textColor="#ffffff" />
<Button
android:id="#+id/bEvents"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#f8bd0e"
android:padding="3dp"
android:text="Events" />
<Button
android:id="#+id/bNearby"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#f8bd0e"
android:padding="3dp"
android:text="Nearby" />
</LinearLayout>
<LinearLayout
android:id="#+id/llFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal" >
<fragment
android:id="#+id/fHome"
android:name="com.example.fragmentstack.Home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
<fragment
android:id="#+id/fEvents"
android:name="com.example.fragmentstack.Events"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
<fragment
android:id="#+id/fNear"
android:name="com.example.fragmentstack.NearBy"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</FrameLayout>
</LinearLayout>
The output of activity_main.xml is
Main Activity:
public class MainActivity extends FragmentActivity implements OnClickListener {
Button home, events, near;
Fragment f1, f2, f3, f4;
FragmentManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
home = (Button) findViewById(R.id.bHome);
events = (Button) findViewById(R.id.bEvents);
near = (Button) findViewById(R.id.bNearby);
home.setOnClickListener(this);
events.setOnClickListener(this);
near.setOnClickListener(this);
manager = getSupportFragmentManager();
f1 = manager.findFragmentById(R.id.fHome);
f2 = manager.findFragmentById(R.id.fEvents);
f3 = manager.findFragmentById(R.id.fNear);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bHome:
if (home.isPressed()) {
home.setBackgroundColor(Color.BLACK);
home.setTextColor(Color.WHITE);
events.setBackgroundResource(R.color.Yellow);
near.setBackgroundResource(R.color.Yellow);
events.setTextColor(Color.BLACK);
near.setTextColor(Color.BLACK);
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.hide(f2);
transaction.hide(f3);
transaction.show(f1);
transaction.commit();
}
break;
case R.id.bEvents:
if (events.isPressed()) {
events.setBackgroundColor(Color.BLACK);
events.setTextColor(Color.WHITE);
home.setBackgroundResource(R.color.Yellow);
near.setBackgroundResource(R.color.Yellow);
home.setTextColor(Color.BLACK);
near.setTextColor(Color.BLACK);
FragmentTransaction transaction1 = getSupportFragmentManager()
.beginTransaction();
transaction1.hide(f1);
transaction1.hide(f3);
transaction1.show(f2);
transaction1.commit();
}
break;
case R.id.bNearby:
if (near.isPressed()) {
near.setBackgroundColor(Color.BLACK);
near.setTextColor(Color.WHITE);
home.setBackgroundResource(R.color.Yellow);
events.setBackgroundResource(R.color.Yellow);
home.setTextColor(Color.BLACK);
events.setTextColor(Color.BLACK);
FragmentTransaction transaction2 = getSupportFragmentManager()
.beginTransaction();
transaction2.hide(f1);
transaction2.hide(f2);
transaction2.show(f3);
transaction2.commit();
}
break;
}
}
}
Now Home extends Fragment. the xml layout of home has one Button and one TextView.Here onClicking Button I'm replacing the Home Fragment with new Update Profile Fragment.
public class Home extends Fragment {
Button btn;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
view = inflater.inflate(R.layout.home, container, false);
init();
return view;
}
private void init() {
btn = (Button) view.findViewById(R.id.bUpdate);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fg = new UpdateProfile();
FragmentTransaction fragmentTransaction = getFragmentManager()
.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fg);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
}
R.id.fragment_container is present in activity_main.xml. Now the problem I'm facing is when clicking the button it is not replacing the fragment with new Fragment.
Now the problem I'm facing is when clicking the button it is not
replacing the fragment with new Fragment.
The transaction does occur but it's not visible as you add that fragment to a container that will be pushed out of the screen(all of your layout's fragments have width set to match_parent so they will fill the LinearLayout's width and the FrameLayout will be pushed out of the screen).
Also you do the replace transaction on a container that doesn't hold the previous fragments, this means that the old fragments will still be visible on the screen(plus the new added fragment).
The system you setup is not the proper way to handle your scenario. From the images it seems you have a tab like layout and in this case you should have only one container in which all of your fragments will reside(to avoid the extra work of showing/hiding the proper fragment and also provide a decent BACK button experience).
Secondly if you're going to work(do transactions) with those fragments you should really add them programmatically as replace will not go well with a static fragments. There are a lot of tutorials out there on how to make a tab like layout with fragments.

Android Fragment, No view found for id inside TabHost

I have a simple Android application with tabs set up using Tabhost and Fragments. On one of the tab pages, the fragment is a listview. What I want to do is when a user clicks on one of the items of the list view, open up a new view with more specific information based on the item clicked but preserving it so that the tabs are still there.
My approach is when a user clicks on a item in the listview, a new fragment is created and then from my main FragmentActivity class that owns all of these fragments and handles the tabbing logic, it will detach the currently shown fragment and add this "new" (singleStationListItem) fragment. The issue I am encountering is that I cannot add my new fragment to the fragmentTransaction with the R.id.realtabcontent and thus, it is not properly added. I get:
03-21 10:50:01.862: E/FragmentManager(1136): No view found for id 0x1010000 (android:attr/theme) for fragment singleStationListItem{40d090a0 #2 id=0x1010000}
where R.id.realtabcontent = 0x01010000;
I can attach it without the Id, but then users are not able to go back ( call addtobackstash() ). I have searched for this errors but other solutions do not relate to tabhost and I seem to do what is required, like call setContextView(...) in onCreate() to the xml file of the layout that includes the framelayout tag that I am trying to attach my fragment to. I can add my tab fragments to the R.id.realtabcontent without a problem. Does anyone know what could be causing my error and how I can fix it?
Note: I follow this tutorial for getting my tabs working. My code is very similar.
http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/
My Code:
activiy_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_body"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"
android:padding="5dp" />
<FrameLayout
android:id="#+android:id/realtabcontent" <--id that I want to set to
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-4dp"
android:layout_weight="0"
android:orientation="horizontal" />
</LinearLayout>
</TabHost>
</LinearLayout>
main_activity.java //parts from my fragment activity class
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Step 1: Inflate layout
setContentView(R.layout.activity_main);
// Step 2: Setup TabHost
initialiseTabHost(savedInstanceState);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
}
}
public void onTabChanged(String tag) { //handles tab changes
TabInfo newTab = (TabInfo) this.mapTabInfo.get(tag);
if (mLastTab != newTab) {
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(this,
newTab.clss.getName(), newTab.args);
ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag); //note it uses the R.id.realtabcontent without any issues here
} else {
ft.attach(newTab.fragment);
}
}
Log.d("fragment manager in activity: ", "" + ft.isEmpty());
mLastTab = newTab;
ft.commit();
this.getSupportFragmentManager().executePendingTransactions();
Log.d("ft ID: ", ft.toString());
}
}
//This is the callback function inside the listview fragment. I created an interface and it is overwritten in here as suggested by the Android SDK guide
public void onStationSelected(String station) {
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
ft.addToBackStack(null);
ft.addToBackStack(null);
//create argument for new fragment that will be created
Bundle b = new Bundle();
b.putString("station", station);
Fragment displayStationInfo = Fragment.instantiate(this, singleStationListItem.class.getName(), b);
Fragment cur = getSupportFragmentManager().findFragmentById(R.id.realtabcontent);
ft.detach(cur);
ft.add(R.id.realtabcontent, displayStationInfo); <-- this line causes the error
ft.commit();
this.getSupportFragmentManager().executePendingTransactions();
}
singleStationListItem.java is here
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = this.getArguments();
getActivity().setContentView(R.layout.single_station_item_view);
TextView txtStation = (TextView) getActivity().findViewById(R.id.station_label);
String station = b.getString("station");
// displaying selected product name
Log.d(TAG, "passed in station information: " + station);
txtStation.setText(station);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = (LinearLayout)inflater.inflate(R.layout.single_station_item_view, container, false);
return v;
}
Any help would be greatly appreciated.
I realize this question was asked a while ago, I am posting an answer for others that may come across this question.
As far as I know, there is no Android id of 'realtabcontent'. In your XML, remove the 'android' part of your id for the FrameLayout.
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
The complete XML code posted on the developer documentation is as follows:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
Good luck and happy coding!

Using a Fragment in Android 2.2

I am using fragments for Android 2.2 (with backward compatibility) for the first time. I created a simple example to see how it works.
Here is the code snapshot.
Main Activity code:
public class FragmentExampleActivity extends FragmentActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
RadioButton radioButton1 = (RadioButton)findViewById(R.id.radioButton1);
radioButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changeView1();
}
});
radioButton1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//changeView1();
}
});
}
protected void changeView1() {
// Create new fragment and transaction
Fragment newFragment = new RadioActivity1();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.relativeLayout, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
Main Activity Layout file (main_activity)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/relativeLayout">
<FrameLayout android:id="#+id/frameLayout" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_alignParentTop="true"
android:layout_above="#+id/radioButtonGroupLayout">
<fragment android:name="com.example.fragmentexample.HelloWorldFragment"
android:id="#+id/generalView" android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RadioGroup android:id ="#+id/radioButtonGroupLayout" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_alignParentBottom="true">
<RadioButton android:id="#+id/radioButton1" android:text="Radio 1"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<RadioButton android:id="#+id/radioButton2" android:text="Radio 2"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<RadioButton android:id="#+id/radioButton3" android:text="Radio 3"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</RadioGroup>
</RelativeLayout>
Initial Fragment Class
public class HelloWorldFragment extends Fragment
{
public HelloWorldFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.hello_world_fragment_layout,null);
return v;
}
}
Fragment which is called when radio button is clicked/checked
public class RadioActivity1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.radio_activity_one_layout,null);
return v;
}
}
layout for second fragment class
<?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" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
snapshot of code to replace the fragment
// Create new fragment and transaction
Fragment newFragment = new RadioActivity1();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.remove(getSupportFragmentManager().findFragmentById(R.id.generalView));
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.relativeLayout, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
My problem is that the fragment is not getting replaced... I can see the HelloFragment Layout behind the second fragment.
You can only remove/replace a fragment programmatically if it was added programmatically in the first place.
Remove the fragment node from main_activity.xml so that frameLayout has nothing in it. Then in your onCreate do something like this:
FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frameLayout, new HelloWorldFragment());
transaction.addToBackStack(null);
transaction.commit();
And then your replace code would look something like:
Fragment newFragment = new RadioActivity1();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frameLayout, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Also, you may need to change HelloWorldFragment to use an overload of LayoutInflater.inflate, add false as the last parameter, attachToRoot.

Android Fragment Duplicate Objects in Layout

I'm trying to build an Android 4.0 App with the new fragments and action bar.
I'm doing well but I have a little problem now.
When I put a fragment inside a tab, and for example, a time picker in the fragment layout, in the emulator it will appear twice, one on top of the other.
Here is my code:
public class NetworksActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.networks);
// setup Action Bar for tabs
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// instantiate fragment for the tab
Fragment networksFragment = new NetworksFragment();
// add a new tab and set its title text and tab listener
actionBar.addTab(actionBar.newTab().setText("Sensors")
.setTabListener(new ActionTabListener(networksFragment)));
}}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/net_frag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="my.package.test.NetworksFragment" />
</FrameLayout>
public class NetworksFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.networks_fragment, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TimePicker
android:id="#+id/timePicker1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
public class ActionTabListener implements ActionBar.TabListener {
private NetworksFragment frag;
// Called to create an instance of the listener when adding a new tab
public ActionTabListener(NetworksFragment fragment) {
frag = fragment;
}
#Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.net_frag, frag, null);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(frag);
}
}
It seems like its putting two fragments (two copies) in the same activity.
Do you know what are causing this?
Thanks in advance.
It looks like you are defining a fragment in XML, which will instantiate it when that layout is inflated (from NetworksActivity.setContentView(R.layout.networks)) then you are creating another instance of it just below that.
Unless I am missing something, that is your problem. No need to define it in XML if you are going to instantiate it manually and add it yourself in code.
I had a similar problem. The way i solved it was to remove this code from my Fragment-class:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
CameraFragment cameraFragment = new CameraFragment();
fragmentTransaction.add(R.id.spinnerFragment, spinnerFragment);
fragmentTransaction.commit();
And left this code from my fragment-XML:
<fragment
android:id="#+id/spinnerFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
class="com.example.SpinnerFragment" />
I guess you can do it the oposite way also :)

Categories

Resources