I have the following activity which launches a fragment when the tab is selected:
public class MainActivity extends Activity implements TabListener {
Fragment f = null;
.....
public void onTabSelected(Tab tab, FragmentTransaction ft) {
.....
if (tab.getPosition() == 0) {
if (initalSync == true) {
progress1.setVisibility(TRIM_MEMORY_UI_HIDDEN);
}
f = new EventFragment();
Bundle data = new Bundle();
data.putInt("idx", tab.getPosition());
f.setArguments(data);
}
if (tab.getPosition() == 1) {
progress1.setVisibility(TRIM_MEMORY_UI_HIDDEN);
f = new MapsFragment();
Bundle data = new Bundle();
data.putInt("idx", tab.getPosition());
f.setArguments(data);
}
.....
ft.replace(android.R.id.content, f);
}
When ever I press the phones back button on any of the fragments it closes my app. I know this is related to the backstack but every method I have tried fails.
any ideas?
You need to add your fragments to the backstack if you don't want the activity to close by the time you press back, all you have to do is calling the following method:
ft.addToBackStack(null)
before you replace and commit your transaction.
This way the fragments injection you are using will be tracked down, and the back button will change to the previos fragment until reaching the first action and then it will close the app.
Regards!
You need to call addToBackstack(null) on the Transaction to add the fragment to the backstack. Then the back button should revert to the previous fragment.
Related
I am having trouble going back to previous fragment on backpress from current fragment.
I have Two fragments and i navigate to second fragment on click and when i try to click back from the second fragment, i want to go back to the previous fragment but instead the app exits on backpress. below is the code i am using..
Fragment1 calling second fragment
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.replace(android.R.id.content, frag, "UserActivity").addToBackStack(null);
transaction.commit();
In second Fragment i have implemented an interface OnBackpress and over riding the below method
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() != 0) {
if(getFragmentManager().findFragmentByTag("UserActivity") != null){
Log.e("UserActivity",getFragmentManager().findFragmentByTag("UserActivity").toString());
getFragmentManager().popBackStack();
};
}
}
But on back press the app exits. Instead i want to go back to previous fragment. What mistake am i doing? please help. thanks
You need to add you first fragment to back stack properly, you are doing it wrong in your first part of the code.
Use the following code instead.
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.replace(android.R.id.content, frag, "UserActivity");
transaction.commit();
Also there is no need to add any code in your onBackPressed after above change.
First, you need to add your fragments to the backstack:
public static void addFragment(FragmentManager fragmentManager, Fragment fragment, int id){
fragmentManager.beginTransaction().add(id, fragment).addToBackStack(null).commit();
}
Then you need to override the onBackPressed, which is a method gets called whenever a user clicks the back button:
#Override
public void onBackPressed() {
super.onBackPressed();
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
button.setVisibility(View.VISIBLE);
}
}
please change to add() instead of replace() in your code..
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.add(android.R.id.content, frag, "UserActivity").addToBackStack(null);
transaction.commit();
This will solve your problem.
I am testing situation where a user goes into my app after the system has terminated the app process due to low RAM. I am seeing unexpected behavior and hoping to get some help.
In my app, I have an activity, lets call it ActivityA, that immediately creates a fragment, Fragment A, and does a fragment replacement. FragmentA displays a ListView with two items in it. If the user clicks the first item, a second fragment, Fragment B is created and replaces FragmentA. Otherwise, another FragmentA is created and replaces the original FragmentA. I'm trying to create a file directory tree. FragmentA is for directories, and FragmentB is for files.
Lets say the user clicks on a file. This is the stage in the test where the user switches to another app, and the system terminates my app's process due to low memory. Then, the user goes back into my app expecting everything to be left the way it was. However, what actually happens is Fragment A (The parent directory) is being displayed instead of Fragment B (the file). When the user clicks the back button, Fragment B (the file) is then displayed. What am I doing wrong that is causing the system to restore the backstack in this way?
Here is an example program to further show what my app is doing:
// ActivityA.java
public class ActivityA extends AppCompatActivity implements onItemClickListener
{
#Override
public void onCreate(Bundle savedInstanceState)
{
FragmentA fragA = new FragmentA();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransation.replace(R.id.basic_frame, fragA);
fragmentTransaction.commit();
}
#Override
public void onItemClick(AdapterView<?> aView, View v, int position, long id)
{
if (position == 0)
{
FragmentB fragB = new FragmentB();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransation.replace(R.id.basic_frame, fragB);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
else
{
FragmentB fragA = new FragmentA();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransation.replace(R.id.basic_frame, fragA);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
}
When you call super.onCreate(), Fragments automatically restore their current state when savedInstanceState is not null.
Therefore if you're expecting to do one time set up by adding your intial Fragment, you should always surround it with an if (savedInstanceState == null) check:
#Override
public void onCreate(Bundle savedInstanceState)
{
// I assume you accidentally left out these lines
super.onCreate(savedInstanceState);
setContentView(R.id.your_content_view);
if (savedInstanceState == null) {
FragmentA fragA = new FragmentA();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransation.replace(R.id.basic_frame, fragA);
fragmentTransaction.commit();
}
}
I've created a fragment that shows gridview and when any griditem is clicked it leds to another fragment. But when I press the physical backbutton the app closes instead of going back to previous fragment (i.e. fragment containing gridview). How can I solve this?
try this one
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
'addToBackStack' is used for moving back to previous fragment, you can use a common Function
in your Main activity for changing fragment.
public void change_fragment(Fragment fragment, int frame) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
//trans.setCustomAnimations(R.anim.enterfrom_left, R.anim.exit_to_right,R.anim.enterfrom_left, R.anim.exit_to_right);
trans.replace(frame, fragment);
trans.addToBackStack("hai" + frame);
trans.commit();
}
you can call it from Main activity like this
change_fragment(new Frag(),R.id.fl_main_frag_container);
you can call it from another fragment like this
((MainActivity)getContext()).change_fragment(new Frag(), R.id.fl_main_frag_container);
I have an activity called MainActivity with 2 fragment (let's call them A and B). This activity shows A on the left and B on the right in case of large display, but, for small display, there is only one frameLayout and I change the fragment in it after I clicked something in the fragment B.
So, for small device, I show initially fragment A and from it I can go to B, (I select a day from my CalendarView in fragment A and then I can go to B).
In B then I can go to another Activity by clicking a button. From that activity I want to came back to my previously activity but I don't know how to have the fragment B already inflated. Right now if I go back to my MainActivity I find fragment A also if I left this activity with B inflated.
I can come back either with the back button on my actionbar or after I close my last activity (the one I go after B).
Can anyone help me?
This is the Main activity class in which I have the two fragments.
public class MainActivity extends AppCompatActivity implements CalendarFragment.OnCalendarSelectedListener{
private ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionBar=getSupportActionBar();
if(findViewById(R.id.left_fragment) != null){
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
AFragment leftFragment = new AFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.left_fragment, leftFragment).commit();
}
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.right_fragment) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
BFragment bFragment = new BFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.right_fragment, bFragment).commit();
}
}
...
//this is how I inflate the fragment B from a click on fragment A
public void onCalendarSelected(int day, int month, int year) {
BFragment bFragment = (BFragment)
getSupportFragmentManager().findFragmentById(R.id.right_fragment);
if (bFragment != null) {
bFragment.updateList(day);
} else {
actionBar.setDisplayHomeAsUpEnabled(true);
BFragment newFragment = new BFragment();
Bundle args = new Bundle();
args.putInt("day",day);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.left_fragment, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
This code works fine but I don't know how to solve my problem.
I have 4 fragments in a FragmentPagerAdapter.
When I am in the 4th fragment and press the back button, it can be returned to previous fragment, it may be the 3rd or 2nd fragment.
But If the previous one is the 3rd one, the app will automatically exit after clicking the back button. What I want is the app can stay on the 3rd fragment after user click the back button on the 4th fragment without automatically exiting. The reason why it happens is because that the two neighbored fragments will taking actions synchronously when user click back button.
How to implement it? Thx.
public void onBackPressed() {
moveTaskToBack(true);
System.out.println(123456);
ViewPager mViewPager = (ViewPager) this.findViewById(R.id.pager);
App atp = this.getApplication();
int count = atp.getFragmentStack().size();
if (count == 0) {
//additional code
} else {
mViewPager.setCurrentItem(2);
}
}
UPDATES(answering comment 1):
My app use FragmentPagerAdapter ,
so I want to use
ViewPager mViewPager = (ViewPager) this.findViewById(R.id.pager);
mViewPager.setCurrentItem(2);
to chang the fragment. Commit does not work, I also need to change the selection bar.
You need to add to back stack your fragments or replace:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(here_your_fragment);
//OR ADD
//fragmentTransaction.add(here_your_fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
So for you solution is:
In activity create variable
public int fragmentPosition;
Then, put the value of your activity or fragment into your adaper. In method where your fragments instantiate or gets pass the position of your fragment to the value of fragmentPosition, like this
yourActivityOrFragment.fragmentPosition = position;
And after that, in method onBackPressed() check for position of fragments
public void onBackPressed() {
if (fragmentPosition == 3) {
finish();
} else {
super.onBackPressed();
}
}