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.
Related
I'm trying to show an image below a button only after the button has been pressed. My problem is that the fragment is shown immediately when the app is started and not only after the button has been pressed.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void say_hello(View view){
Fragment fragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment2, fragment).commit();
}
}
public class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.news_articles, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="fill_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:text="PRESS THIS"
android:id = "#+id/test_button"
android:background="#drawable/test_button"
android:onClick="say_hello"
/>
<fragment
android:id="#+id/fragment2"
android:name="com.example.tic_tac_toe.ExampleFragment"
android:layout_width="match_parent"
android:layout_height="643dp" />
</LinearLayout>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/cool_dog">
</ImageView>
I'm guessing the fragment shows up when the app is started because of the name I give to the fragment in the XML, but the fragment needs a name otherwise I only get error. How do I get the fragment to display nothing before I have clicked the button?
Instead of using <fragment /> view in your xml, you can use Framelayout and add your fragment to this Framelayout on button click using the following code -
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.mainframe, fragment);
transaction.commit();
Where mainframe is the id of Framelayout.
You can try doing this
android.app.Fragment fragment = getActivity().getFragmentManager().findFragmentByTag("YOUR_FRAGMENT_TAG");
getActivity().getFragmentManager().beginTransaction().hide(fragment);
inside your click event.
I have developed an app, in that I have a fragment transaction,
MainActivity contains Fragment View.
MainActivity have three Button on top of the screen, that remain same when we go this Activity to another Fragment, only MainActivity Fragment part change when we click out of three.
But, my problem is that when I move from the this MainActivity to Fragment when click on First-Button that is OK, but when I click on Second-Button, result is overwrite the screen with first Fragment to another Fragment.
it is in same Activity so , I can not remove Fragment through remove(fr).commit();
Because if I do that then it become non-clickable may be fragment remove so not response on click of next button.
overall result, It display both FirstFragment and NewFragment Screen , when i move to NewFragment how i remove the FirstFragment screen ?
In MainActivity three button have following code to change fragment :
Main Activity :
public class MasterActivity extends Activity {
ImageView imgOne, imgTwo, imgThree;
Fragment fr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master);
imgOne = (ImageView) findViewById(R.id.imgOne);
imgTwo = (ImageView) findViewById(R.id.imgTwo);
imgThree = (ImageView) findViewById(R.id.imgThree);
imgOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
fr = new FirstFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.addToBackStack(null);
//fragmentTransaction.remove(fr).commit();
//getFragmentManager().beginTransaction().remove(fr).commit();
fragmentTransaction.commit();
}
});
imgTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
fr = new SecondFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.addToBackStack(null);
//fragmentTransaction.remove(fr).commit();
// getFragmentManager().beginTransaction().remove(fr).commit();
fragmentTransaction.commit();
}
});
its xml file like following :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000"
android:gravity="bottom"
android:weightSum="3" >
<ImageView
android:id="#+id/imgOne"
android:layout_width="0dp"
android:layout_height="27dp"
android:layout_gravity="center"
android:layout_weight="1"
android:src="#drawable/img1" />
<ImageView
android:id="#+id/imgTwo"
android:layout_width="0dp"
android:layout_gravity="center"
android:layout_height="27dp"
android:layout_weight="1"
android:src="#drawable/img2"/>
<ImageView
android:id="#+id/imgThree"
android:layout_width="0dp"
android:layout_gravity="center"
android:layout_height="27dp"
android:layout_weight="1"
android:src="#drawable/img3" />
</LinearLayout>
<fragment
android:id="#+id/fragment_place"
android:name="packagename.FirstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.87"/>
<LinearLayout/>
<LinearLayout/>
First Fragment :
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View r = inflater.inflate(R.layout.first_fratgment, container, false);
return r;
}
}
Second Fragment :
public class SecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View r = inflater.inflate(R.layout.second_fratgment, container, false);
return r;
}
}
But when click on one button Fragment button to another it display both first and second Fragment screens.
So how to resolve it and how to remove first view when second click?
I used this
fragmentTransaction.remove(fr).commit();
and this
getFragmentManager().beginTransaction().remove(fr).commit();
but it's not working.
Fragment declared in the layout are treated differently by Android. Replace
<fragment
android:id="#+id/fragment_place"
android:name="packagename.FirstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.87"/>
with a FrameLayout, or a subclass of ViewGroup of your choice, and handle all the transactions programmatically. The rest looks good to me
Its better to use a viewGroup or a layout/FrameLayout instead of fragments (fragment navigations on button clicks in an Activity). Because fragments have their own lifecycle and fragment hold thier views or are not killed when you do fragment transition within an activity.
Although if you still want to go with fragment, first load a fragment of first button click and handle the click events of other two buttons by removing the fragment previously attached (Fragment attached to first button click).
This can be done by:
getSupportFragmentManager().beginTransaction().remove(YOUR_FIRST_FRAGMENT).commit();
and after this you can write a code to add fragment in this place,
getFragmentManager().beginTransaction().replace(YOUR_FIRST_FRAGMENT, new YourSecondButtonFragment()).commit(); and hence this can be done for your third button click too, just need to change the fragment attached to second button.
I hope this will help you.
Fragments that are hard coded in XML, cannot be replaced. Use the FramLayout as a fragment container instead.
in your XML replace
<fragment
android:id="#+id/fragment_place"
android:name="packagename.FirstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.87"/>
<LinearLayout/>
with
<FrameLayout
android:id="#+id/contentFragment"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="2" />
Now, Do follow the following code style to achieve your goal:
First set the onClickListeners to all the imageviews:
like: imgOne.setOnClickListener(this);
#Override
public void onClick(View v) {
Fragment fragment = null;
switch (v.getId()) {
case R.id.imgOne:
fragment = new Fragment1();
break;
case R.id.imgTwo:
fragment = new Fragment2();
break;
}
if (fragment != null) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.contentFragment, fragment).commit();
} else {
Log.e(LOG_TAG, "Error in fragment transaction.");
}
}
Hope this helps.
you can use: getSupportFragmentManager().beginTransaction().remove(fragment).commit();
Hope this will help.
Make necessary changes. Replace your activity and xml with this.
It should run solid if you do.
public class MasterActivity extends Activity {
ImageView imgOne, imgTwo, imgThree;
Fragment fr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master);
imgOne = (ImageView) findViewById(R.id.imgOne);
imgTwo = (ImageView) findViewById(R.id.imgTwo);
imgThree = (ImageView) findViewById(R.id.imgThree);
getFragmentManager().beginTransaction().add(R.id.fragment_place, new FirstFragment()).commit();
imgOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction().replace(R.id.fragment_place, new FirstFragment()).commit();
}
});
imgTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction().replace(R.id.fragment_place, new SecondFragment()).commit();
}
});
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000"
android:gravity="bottom"
android:weightSum="3" >
<ImageView
android:id="#+id/imgOne"
android:layout_width="0dp"
android:layout_height="27dp"
android:layout_gravity="center"
android:layout_weight="1"
android:src="#drawable/img1" />
<ImageView
android:id="#+id/imgTwo"
android:layout_width="0dp"
android:layout_gravity="center"
android:layout_height="27dp"
android:layout_weight="1"
android:src="#drawable/img2"/>
<ImageView
android:id="#+id/imgThree"
android:layout_width="0dp"
android:layout_gravity="center"
android:layout_height="27dp"
android:layout_weight="1"
android:src="#drawable/img3" />
</LinearLayout>
<FrameLayout
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.87"/>
<LinearLayout/>
<LinearLayout/>
when i move to NewFragment how i remove the first frament screen ?
well you can do that by hiding the old(first) Fragment source
getSupportFragmentManager().beginTransaction().hide(getSupportFragmentManager()
.findFragmentById(R.id.the_id_of_my_first_fragment));
you can also get him(the first fragment) back by the same approach source
getSupportFragmentManager().beginTransaction().show(getSupportFragmentManager()
.findFragmentById(R.id.the_id_of_my_first_fragment));
This approach buys flexibility and not re-changing your app's architecture, and logic, and also one line of work
im always late to a party (:
copy and pest code in your button click event.
fr = new FirstFragment();
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
this is completed work.
When frButton is clicked FragmentOne should open and MainActivity should be hidden but Components of MainActivity is still accessible in FragmentOne, which is unwanted.
How to fix it?
code for MainActivity:
public void gofag1(View v) {
// TODO Auto-generated method stub
FragmentOne frag = new FragmentOne();
FragmentManager fm = getFragmentManager(); // import
FragmentTransaction ftr = fm.beginTransaction(); // import
ftr.add(R.id.mainlayout, frag, "keyFrag");
ftr.addToBackStack(null);
ftr.commit();
}
code for FragmentOne:
public class FragmentOne extends Fragment {
public FragmentOne() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_one, container,
false);
return v;
}
}
code for FragmentOne layout... R.layout.fragment_one
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="com.megavb.le.FragmentOne" >
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/tOnOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="22dp"
android:text="#string/a1" />
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="reedToggleValue"
android:text="ToggleButton"
android:textSize="30sp" />
code for MainActivity layout.... R.id.mainlayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="gofag1"
android:text="fOne" />
</RelativeLayout>
Please see the picture for better understanding...
So, you should be using ftr.replace instead of ftr.add
public void gofag1(View v) {
// TODO Auto-generated method stub
FragmentOne frag = new FragmentOne();
FragmentManager fm = getFragmentManager(); // import
FragmentTransaction ftr = fm.beginTransaction(); // import
//Notice the change here
ftr.replace(R.id.mainlayout, frag, "keyFrag");
ftr.addToBackStack(null);
ftr.commit();
}
Hope this helps!
EDIT: Well, without more information I'm going to take another stab at this.
In your mainlayout.xml you need to define a Fragment Container a simple method of doing this would be to use a layout file like the one that follows as a base for your Activity.
<?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:id="#+id/fragment_container">
</FrameLayout>
after defining this new fragment container you can programmatically add fragments to it by referencing it's ID.
The next step is to move your original MainActivty code into a new fragment!
This is the code for fragment_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:onClick="gofag1"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Here we create a new layout that simply contains a button.
Next we create the actual fragment
public class FragmentMain extends Fragment {
public FragmentMain() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_main, container,
false);
}
From here we can change our Main activity OnCreate code to
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
FragmentMain frag = new FragmentMain();
FragmentManager fm = getFragmentManager(); // import
FragmentTransaction ftr = fm.beginTransaction(); // import
ftr.add(R.id.fragment_container, frag, "keyFrag");
ftr.addToBackStack(null);
ftr.commit();
}
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.
I would like to use one Activity which holds several fragments and navigate among the fragments. For example, in the activity, there is a list view which is a fragment, when user select one item from the list, the view will navigate to another fragment, How could this be implemented?
I know there is a nice tutorial on the developer site, but it handles the tablet screen in which two pane layout with one list fragment and one detailed fragment showing in one screen. I only want to navigate among fragments without show two fragments in one screen.
Are there tutorials can teach me how to do it?
In the nutshell the answer to your question is to notify your host activity and then have your host activity replace your current fragment container using FragmentManager.
One of the approach is to make an interface in your first fragment, have your host activity register/listen (implement) to this interface and then have your FragmentManager to replace the container content with the second fragment on listener callback.
I'm not sure about tutorial but here is my snippet:
First Fragment
public class First extends Fragment{
private static onMySignalListener listener;
//call this function from whatever you like i.e button onClickListener
public void switchWindow() {
if(listener != null){
listener.onMySignal();
}
}
public interface onMySignalListener {
//customize this to your liking
//plain without argument
void onMySignal();
//with argument
void onMySignalWithNum(int mNum);
}
public static void setOnMySignalListener(onMySignalListener listener) {
First.listener = listener;
}}
Host Activity
public class HostActivity extends FragmentActivity implements onMySignalListener{
private final String ADD_TAG_IF_NECESSARY = "mTag";
#Override
public void onCreate(Bundle ssi) {
setContentLayout(R.layout.main);
FirstFragment.setOnMySignalListener(this);
}
#Override
public void onMySignal() {
//if you're using compat library
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
//initialize your second fragment
sfragment = SecondFragment.newInstance(null);
//replace your current container being most of the time as FrameLayout
transaction.replace(R.id.container, fragment, ADD_TAG_IF_NECESSARY);
transaction.commit();
}
#Override
public void onMySignalWithNum(int mNum) {
//you can do the same like the above probably with your own customization
}}
This is only an example on how you'd implement interface, kindly tidy it up by yourself. And please be noted though that this is not effective if you have a lot of fragment wanting to notify your host activity about something. doing so will lead you to implement various listener to your host activity.
I think this will be useful for you. It is example of two fragments in one screen works independently.
MainActivity :
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Fragment newFragment = new Test();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.UprLayout, newFragment);
// transaction.addToBackStack(null);
transaction.commit();
Fragment newFragment2 = new TestRight();
FragmentTransaction transaction2 = getFragmentManager().beginTransaction();
transaction2.add(R.id.dwnLayout, newFragment2);
// transaction.addToBackStack(null);
transaction2.commit();
}
}
main_activity.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/UprLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" />
<LinearLayout
android:id="#+id/dwnLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" />
</LinearLayout>
Fragment Test :
public class Test extends Fragment {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test, container, false);
return view;
}
}
Fragment TestRight :
public class TestRight extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test_right, container, false);
return view;
}
#Override
public void onStart() {
super.onStart();
Button button = (Button)getActivity().findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Fragment newFragment = new Right2nd();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
transaction.replace(R.id.dwnLayout, newFragment);
transaction.addToBackStack("aa");
transaction.commit();
//transaction.add(R.id.frag, newFragment).commit();
}
});
}
}
test.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:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="test"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="50sp" />
</LinearLayout>
test_right.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:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test right"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="45sp" />
</LinearLayout>
Fragment Right2nd :
public class Right2nd extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View vw = inflater.inflate(R.layout.right_2nd, container, false);
return vw;
}
}
right_2nd.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:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right 2nd"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="50sp" />
</LinearLayout>
I know this is quite old question but this is currently implemented in Navigation Component https://developer.android.com/guide/navigation/
Here is a very nice tutorial about it. MULTIPLE FRAGMENTS STACK IN EACH VIEWPAGER TAB
I think ChildFragment
would do the job for you. Ignore the Tab ViewPager. It's performing the same thing in multiple tabs. Hope this helps a bit.