I've implemented few Fragments in a FragmentTabHost, using:
Inside FragmentActivity Class:
FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreateView()");
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("audio").setIndicator("Audio"),
AudioFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("video").setIndicator("Video"),
VideoFragment.class, null);
mTabHost.setOnTabChangedListener(this);
}
In one of the fragment say AudioFragment there is a button which is supposed to open a new fragment over the current fragment of AudioFragment.
Inside AudioFragment.class
#Override
public void onClick(View button) {
switch (button.getId()) {
case R.id.bOpenNewFragment:
// WHAT TO CODE, TO REPLACE THE CURRENT FRAGMENT OF AudioFragment
break;
}
}
I tried the usual code using:
Fragment fragment = new ShowAudioDetailsFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.realtabcontent, fragment);
transaction.addToBackStack(null);
transaction.commit();
But, it was creating problems when I switched to another tabs (like state was not maintained & view of new fragment was merging with the layout of other tabs).
So How can I replace the fragment with the fragment opened within FragmentTabHost
Thank You
Just add this line
((RelativeLayout) findViewById(R.id.realtabcontent)).removeAllViews(); // whatever layout you have
before :
transaction.replace(R.id.realtabcontent, fragment);
Related
I am using recyclerview in my app. I want to start a fragment when click on image view. But i don't know how to. Also i want to put data when starting fragment. I know how to start the activity with below code. But how can i start fragment same way?
Edited Code
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.layoutContent, frag);
ft.commit();
Fragments cannot be started, they must be added to a container.
Fragments aren't meant to function on their own, they need an enclosing Activity.
Having the following layout:
[...]
<FrameLayout android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
[...]
You place the fragment in it like such:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, newFragment);
transaction.commit();
You pass arguments to the fragment by using Bundle and creating the fragment as follows:
TestFragment newFragment = new TestFragment();
Bundle args = new Bundle();
args.putString("Hello world!");
newFragment.setArguments(args);
This has to be done before the transaction.
For further info refer to the official documentation
Note on edited code: you have to call the transaction from inside the Activity the FrameLayout is part of. Alternatively use a rather dirty workaround:
In Main:
public class Main extends Activity{
public static Main currentInstance;
public void onCreate(Bundle boomerang){
currentInstance = this;
}
}
In the Playlist activity then use Main.currentInstance.getSupportFragmentManager() etc.
But I wouldn't recommend it.
In order to start a fragment you need to make use of the fragment manager.
YourFragment yourFragmentInstance = YourFragment.newInstance("Hello", 12);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
//Fragment is hosted by an activity, and the activity must have a layout
//or a container for the fragment to be nested in, in this case it will be
//a FrameLayout with an id fragment_container
fragmentTransaction.replace(R.id.fragment_container, yourFragmentInstance);
fragmentTransaction.commit();
And you can pass in arguments to your fragment like this:
public class YourFragment extends Fragment {
public static YourFragment newInstance(String paramOne, int paramTwo) {
YourFragment fragment = new YourFragment();
Bundle b = new Bundle();
//set params/arguments for fragment
b.putString("param_one", paramOne);
b.putInt("param_two", paramTwo);
fragment.setArguments(b);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get the params you passed in
Bundle bundle = getArguments();
String paramOne = bundle.getString("param_one");
String paramTwo = bundle.getInt("param_two");
}
}
Note: I've not tested this code.. This is just an idea :)
I'm a beginner in Android programming.So i'm going through some Sample Projects and Blogs.I came up on this code , which i want to know why is it used ?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
InterpolatorFragment fragment = new InterpolatorFragment();
transaction.replace(R.id.sample_content_fragment, fragment);
transaction.commit();
}
}
transaction.replace(R.id.sample_content_fragment, fragment);
This tells that in sample_content_fragment FrameLayout remove the current displaying fragment and show new fragment fragment (second parameter)
transaction.commit();
This tells that everything is done with fragment and this is right time to replace the fragment
for more details see this link
I have a FragmentActivity that holds a Fragment(ContainerFragment) with a FragmentStatePagerAdapter that also nested two Fragments (a map and a list). For not getting a nullpointer after orientation change I have to set ContainerFragment setRetainInstance(true) the nested Fragments cannot be setRetainInstance(true), because there would be a exception "Can't retain nested fragments". Everything works fine with orientation change, but when i start a new Detail Fragment from the ListFragement I get "Can not perform this action after onSaveInstanceState"
I searched for answers for both exceptions but nothing worked for me.
in MainActivity:
containerFragment = new ContainerFragment();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
if (findViewById(R.id.fragment_container) != null) {
transaction
.replace(R.id.fragment_container, containerFragment );
}
transaction.addToBackStack(null);
transaction.commit();
in ContainerFragment:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
// If not set, there is a NPE on orientation change
setRetainInstance(true);
// load slide menu items
mTabStrings = getResources().getStringArray(R.array.tabs_array);}
public class MyPagerAdapter extends FragmentStatePagerAdapter {
public MyPagerAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
MapFragment mapFragment = (MapFragment ) Fragment
.instantiate(getActivity(),
MapFragment .class.getName());
return mapFragment ;
case 1:
ListFragment listFragment = (ListFragment ) Fragment
.instantiate(getActivity(),
ListFragment .class.getName());
return listFragment ;
default:
ListFragment listFragment = (ListFragment ) Fragment
.instantiate(getActivity(),
ListFragment .class.getName());
return listFragment ;
}
and this method in main activity is triggerd from ListFragment and works before orientation change but not after, with "Can not perform this action after onSaveInstanceState" after transaction.commit()
#Override
public void onItemSelected(int position) {
// Create fragment and give it an argument for the selected article
XYFragment xyFragment = new XYFragment ();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
// Replace whatever is in the fragment_container view with this
// fragment,
// and add the transaction to the back stack so the user can
// navigate back
if (findViewById(R.id.fragment_container) != null) {
transaction.replace(R.id.fragment_container, xyFragment);
}
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
I have a MainActivity (FragmentActivity) that has a FragmentTabHost.
public class FragmentTabs extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("classA").setIndicator("Class A"),
ClassA.class, null);
mTabHost.addTab(mTabHost.newTabSpec("classB").setIndicator("Class B"),
ClassB.class, null);
mTabHost.addTab(mTabHost.newTabSpec("classC").setIndicator("Class C"),
ClassC.class, null);
}
}
ClassA, ClassB and ClassC are all Fragments (android.support.v4.app.Fragment).
I need to pass data (and call methods) on the Fragments. How can I get a reference of each of the Fragments, like this:
ClassA mClassAFragment = ???;
I’ve tried using getSupportFragmentManager().findFragmentByTag() and I’ve also tried exploring the capabilities of mTabHost. Nothing can get them.
Can you suggest a way to do this or suggest an alternative approach?
And i tried used this...
Bundle arguments = new Bundle();
arguments.putString("some id string", "your data");
YourFragment fragment = new YourFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().add(R.id.fragmentid, fragment).commit();
but i dont know how can use this R.id.fragmentid if my add tabs is well:
mTabHost.addTab(mTabHost.newTabSpec("classA").setIndicator("Class A"),
ClassA.class, null);
Anyone help me?
Define the Fragments in your Activity as public. Then in each Fragment you also reference the Activity.
In your Activity:
public ClassAFragment aFragment;
...
// during initialization:
aFragment = new ClassAFragment();
// or you get it from your TabHost
FragmentManager fm = getFragmentManager();
aFragment = fm.findFragmentByTag("ClassA");
aFragment.mActivity = this;
// same with B and C
In your Fragments:
public MainActivity mActivity;
...
// in Fragment C
String newText = mActivity.aFragment.editText.getText().toString() + mActivity.bFragment.editText.getText().toString();
textView.setText(newText);
I hava a fragment named DetailFragment which extends Fragment class with neccessary Override methods:
public class DetailFragment extends Fragment{
//Some neccessary methods are over here
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.details, container, false);
return view;
}
}
I hava a main activity: FragmentActivity extends FragmentActivity which set content: setContentView(R.layout.main);. If I want to add DetailFragment from FragmentActivity, I have to declare a LinearLayout (or whatever layout) with android:id="#+id/container_fragment" inside the main.xml layout file. With this way, I can add a DetailFragment:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DetailFragment df = new DetailFragment();
ft.add(R.id.container_fragment, df);
ft.commit();
However, I can only add 1 DetailFragment into that container_fragment. If I want to add 2 or more DetailFragment from the activity, do I have to add 2 or more other container_fragment in the main.xml layout? And if not, what I should do and can you give an example? Thanks!
The layout can contain several fragments, you just have to specify different tags when calling the add function of the FragmentTransaction class.
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container_fragment, new DetailFragment(), "df_1");
ft.add(R.id.container_fragment, new DetailFragment(), "df_2");
ft.commit();