I am making a simple demo project using Fragments, in which i am calling SecondFragment from FirstFragment on button click.
And i called SecondFragment without any issue, but i getting view of both the Fragments SecondFragment and FirstFragment
So where i am doing mistake ?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new FirstFragment()).commit();
}
}
public static class FirstFragment extends Fragment {
Button buttonCallSecondFragment;
public FirstFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container,
false);
buttonCallSecondFragment = (Button) rootView.findViewById(R.id.button1);
buttonCallSecondFragment.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, fragment);
ft.commit();
}
});
return rootView;
}
}
public static class SecondFragment extends Fragment {
public SecondFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_second, container,
false);
return rootView;
}
}
}
You need to remove the first fragment, you can do that either by usingreplace or first calling remove then add
To be able to press the back button add the transaction to the back stack,you do that by calling addToBackStack(tag) on your fragment manager. Tag may be null.
You are adding fragment on already displaying fragment in your android app.
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, fragment);
ft.commit();
Do not add fragment but replace fragment when already one fragment is loaded on activity.
So for implementing that :
Please add your code in OnCreate() and add below code to your click listener :
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
Thank you.!!
if you want to replace fragment you should call replace in place of add :
buttonCallSecondFragment = (Button) rootView.findViewById(R.id.button1);
buttonCallSecondFragment.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
}
});
You are adding the fragment so it will come on top of another fragment give background color to rootview of scecond fragment
you can also load that as Nested fragment
public void addFragB() {
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
SecondFragment 2ndfrag = new SecondFragment();
childFragTrans.add(R.id.fragA_LinearLayout, 2ndfrag);
//childFragTrans.addToBackStack("");
childFragTrans.commit();
}
No, you cannot communicate between fragments like this. You need to communicate between fragments via the container activity.
I suggest, you make a navigation method in your activity and switch/call between fragments from there.
Below is a small snippet:
In your container activity:
Fragment fragment;
public void navigateTo(Fragment newFragment,boolean addToBackStack) {
this.fragment = newFragment;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.fragment_container, newFragment);
if(addToBackStack)
ft.addToBackStack(fragment.getClass().getSimpleName());
ft.commit();
}
If you are going from Fragment1 to Fragment2 then in your Fragment1 do the following:
((YourContainerActivity) getActivity()).navigateTo(new Fragment2(),false); //if you want to add to back stack make 2nd argument true.
private void selectItem(int position) {
selectedPosition = position;
// update the main content by replacing fragments
fragment = null;
fragmentStack = new Stack<Fragment>();
switch (position) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
}
//redirect the screen
if (fragment != null) {
fragmentManager = getSupportFragmentManager();
redirectScreen(fragment);
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
Related
From my main activity, pressing Settings button opens an AppCompatActivity with FrameLayout as the container for the fragments. In OnCreate method, I'm adding the fragment which is a PreferenceScreen container.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
Toolbar toolbar = (Toolbar) findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
ab.setTitle("Settings");
}
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = null;
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragment = SettingsFragment.newInstance(null);
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
}
Pressing again another button called Options, opens replaces fragment with Options fragment adding the current class to backstack.
#Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) {
FragmentManager manager = getSupportFragmentManager();
SettingsSubscreenFragment fragment = null;
Bundle args = new Bundle();
switch (pref.getKey()) {
case "pref_key_rejection_options":
getSupportActionBar().setTitle("Rejection Options");
fragment = SettingsSubscreenFragment.newInstance("Options");
break;
}
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, pref.getKey());
if (fragment != null) {
fragment.setArguments(args);
}
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.fragment_container, fragment, pref.getKey());
ft.addToBackStack(null);
ft.commit();
return true;
}
When I press the Up Button, I'm just replacing the Options fragment to the first fragment, Settings, which does not pop the back stack.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getSupportActionBar().setTitle("Settings");
FragmentManager fragmentManager;
FragmentTransaction ft;
Fragment fragment = null;
if (getSupportFragmentManager().findFragmentByTag("pref_key_options") != null) {
fragmentManager = getSupportFragmentManager();
ft = fragmentManager.beginTransaction();
fragment = SettingsFragment.newInstance(null);
ft.replace(R.id.fragment_container, fragment);
ft.commit();
fragmentManager.getFragments().clear();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
return super.onOptionsItemSelected(item);
}
So, opening the Options fragment again will add another to back stack and onBackPress, it only pops the topmost and leaves its shadow overlapping the other one registered in back stack.
#Override
public void onBackPressed() {
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount >= 1) {
getSupportActionBar().setTitle("Settings");
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
The almost the same situation is like from here, third picture of the question, but I can't make it work with their suggestions.
What am I doing wrong and what I can do to make this work? Thanks a lot.
Check FragmentTransaction , SettingsSubscreenFragment and SettingsFragmentare extending android.support.v4.app.Fragment . If not , try
class YourFragments extends android.support.v4.app.Fragment
in your fragment classes.
all!
I have 2 fragments. First one appears at start, second one adds with button "Add", using the same container.I am trying to add fragment to the back stack with method addToBackStack, but when I click "back-button" my app hides instead of showing me the first fragment. What is wrong?
public class MainActivity extends AppCompatActivity {
FirstFragment fragment1;
SecondFragment fragment2;
FragmentTransaction fragmentTransaction;
FragmentManager fm;
Button add;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fragment1 = new FirstFragment();
fragment2 = new SecondFragment();
add = (Button) findViewById(R.id.add);
fm = getFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.add(R.id.container, new FirstFragment());
fragmentTransaction.commit();
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.container, new SecondFragment());
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
}
addToBackStack() on fragment transaction is not enough, we have to handle the popping up of the back stack upon Back button pressed by ourselves.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
I have a ListView that gets and shows some data from RSS.I am showing on ListView and with onClickListener I show detail of list element.There is no problem until here.But My ListView class and detail class are both Fragment.When I want to back to List fragment from detail , it is not return.How to from detail to List fragment?Here is some codes;
public class BlogPostsFragment extends Fragment{
...
}
public class BlogDetailFragment extends Fragment{
...
}
Here is the fragment transaction in Activity;
private void displayView(int position) {
fragment = null;
switch (position) {
case 0:
fragment = new BlogPostsFragment();
break;
default:
break;
}
if (fragment != null) {
fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(drawerList.get(position));// Burada Fragment'ın titleı
// veriliyor.
mDrawerLayout.closeDrawer(mDrawerList);
} else {
Log.e("BlogMainPageActivity",
"Fragment oluşturulurken hata meydana geldi!");
}
}
Here is the code fragment transaction;
vi.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
BlogDetailFragment bdf = new BlogDetailFragment();
Bundle bundle = new Bundle();
bundle.putString("title", currentItem.getTitle());
bundle.putString("description", currentItem.getDesc());
bundle.putString("pubDate", currentItem.getPubDate());
bundle.putString("link", currentItem.getLink());
bdf.setArguments(bundle);
fragmentManager.beginTransaction()
.replace(R.id.frame_container, bdf).commit();
}
});
I begin transaction in an activity.So I am calling BlogPostsFragment from Activity.
Here is what you should do onClick:
String fragmentTag = getFragmentTag();
FragmentTransaction fragmentTransaction = FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
BlogDetailFragment bdf = (BlogDetailFragment) getFragmentManager().findFragmentByTag(fragmentTag);
if(BlogDetailFragment == null) {
bdf = new BlogDetailFragment();
//ADD BUNDLE HERE
}
fragmentTransaction.replace(R.id.frame_container, bdf, fragmentTag);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction = null;
When you replace your list fragment with the detail fragment, you can add the list fragment to the back stack. This will put the list fragment on the top of the back stack, popping it when the user press back. Modify your code as so:
vi.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
BlogDetailFragment bdf = new BlogDetailFragment();
Bundle bundle = new Bundle();
bundle.putString("title", currentItem.getTitle());
bundle.putString("description", currentItem.getDesc());
bundle.putString("pubDate", currentItem.getPubDate());
bundle.putString("link", currentItem.getLink());
bdf.setArguments(bundle);
fragmentManager.beginTransaction()
.replace(R.id.frame_container, bdf).addToBackStack(null).commit();
}
});
I have a Fragment Class
and I have a linear layout clickable
and a button clickable.
So I want to know that when I click linear layout it should start fragment 1
and when I click button it should start fragment 2
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
LinearLayout l = (LinearLayout) rootView.findViewById(R.id.line1);
l.setOnClickListener(this);
Button b = (Button) rootView.findViewById(R.id.map_button);
b.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
Fragment frag = new Fragment1();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, frag);
ft.addToBackStack(null);
ft.commit();
Fragment frag = new Fragment2();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, frag);
ft.addToBackStack(null);
ft.commit();
Add a onClickListener on your button and try that to show your fragment when it is clicked.
#Override
public void onClick(View v) {
Fragment fragment = new Fragment1();
FragmentTransaction fragmentTr = getFragmentManager().beginTransaction();
fragmentTr .setCustomAnimations(android.R.animator.fade_in,
android.R.animator.fade_out);
if (fragment.isHidden())
fragmentTr.show(fragment);
}
Edit:
You can get which view is clicked with a switch case statement:
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.Button:
// show fragment x
case R.id.LinearLayout:
// show fragment y
}
}
your onClick method has to know what was clicked when you say setOnClickListener(this) you refer to the onClick method of the class .in your code it doesn't matter what the user clicks the whole onClick method will be executed . in order to specify the right block of code to be executed you can use Switch and case.
I am trying to implement card flip animation to my fragments, I am following the tutorial at the Developer website http://developer.android.com/training/animation/cardflip.html
However I am getting a weird error, I downloaded the sample app from the Developer website, which to my amazement works fine but when I replace the code in my particular activity it gives me an error:
The method setCustomAnimations(int, int) in the type FragmentTransaction is not applicable for the arguments (int, int, int, int)
Here is the problem code:
private View.OnClickListener on = new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out);
//Fragment1_2 fragment1_2 = new Fragment1_2();
fragmentTransaction.replace(R.id.realtabcontent, new Fragment1_2());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
};
Edit
If I comment the first two or the last two arguments to setCustomAnimation, everything just works fine, however I dont get the animation back press which I know is an implementation issue. Below is the complete code of this fragment's class file:
public class FragmentTab1 extends Fragment {
MenuItem mMenuItem;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);
ActionBar actionBar = getActivity().getActionBar();
// actionBar.setSubtitle("mytest");
actionBar.setTitle("Reminders");
setHasOptionsMenu(true);
Button b = (Button)rootView.findViewById(R.id.button1);
b.setOnClickListener(on);
b.setText("Check");
return rootView;
}
private View.OnClickListener on = new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.setCustomAnimations(
// R.animator.card_flip_right_in, R.animator.card_flip_right_out);
R.animator.card_flip_left_in, R.animator.card_flip_left_out);
//Fragment1_2 fragment1_2 = new Fragment1_2();
fragmentTransaction.replace(R.id.realtabcontent, new Fragment1_2());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
};
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater =getActivity().getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
mMenuItem = item;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
switch (item.getItemId()) {
case R.id.info:
FragmentContact fragmentcontact = new FragmentContact();
fragmentTransaction.replace(R.id.realtabcontent, fragmentcontact, "Fragment1_2");
mMenuItem.setEnabled(false);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
default:
break;
}
return true;
}
#Override
public void onStart(){
ActionBar actionBar = getActivity().getActionBar();
actionBar.setTitle("Reminders");
FragmentManager Fm = getFragmentManager();
Fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
super.onStart();
}
#Override
public void onResume(){
ActionBar actionBar = getActivity().getActionBar();
actionBar.setTitle("Reminders");
FragmentManager Fm = getFragmentManager();
Fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
super.onResume();
}
}
Any hints where I am going wrong would be regarded in great esteem!