In my app, I have only one Activity which hosts several fragments.
The layout of my activity is(main.xml):
<LinearLayout...>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/fragment_placeholder">
</FrameLayout>
</LinearLayout>
My only Activity:
public class MyActivity extends FragmentActivity{
...
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.main);
//I dynamically add fragments into fragment_placeholder of the layout
FirstFragment firstFragment = new FirstFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_placeholder, FirstFragment, "first");
fragmentTransaction.commit();
}
}
I my above activity, I dynamically add the first fragment to layout. The other fragments replace this fragment accordingly.
I know when user press back button to exit the app, by default, my app will still run on background.
what I want however is to kill the app process when user seeing the firstFragment and press the back button (exits the app). But how can I kill my app technically(programmatically) in Android?
I end up killing my app process by:
android.os.Process.killProcess(android.os.Process.myPid())
you can override the back button behaviour by using below code and kill your activity
public void onBackPresed(){
finish();
}
Related
I want to add password screen always at top of stack when app opens from background. I am able to find out method when app comes from background using ActivityLifecycleCallbacks or LifecycleObserver and can show password screen in onStart of base activity. but for few seconds, user see existing activity from where it went to background and then intents to password activity. I want a way so that i can add password activity when app is going to background. but with the methods, i am able to know only when app has already went to background. There is no way that i can add password activity to stack without launching that.
You can use fragments in your BaseActivity:
Activity Class:
public class BaseActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ifConditionTrue) {
//Launch whatever fragment you want
} else {
addFragment(new PasswordFragment());
}
}
// Replace current Fragment with the destination Fragment.
public void addFragment(Fragment destFragment) {
// First get FragmentManager object.
FragmentManager fragmentManager = getSupportFragmentManager();
// Begin Fragment transaction.
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Replace the layout holder with the required Fragment object.
fragmentTransaction.replace(R.id.fragment_container, destFragment);
fragmentTransaction.addToBackStack(null);
// Commit the Fragment replace action.
fragmentTransaction.commit();
}}
base_activity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BaseActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top" />
</androidx.constraintlayout.widget.ConstraintLayout>`
I have an app in which I swap two fragments. The fragments are in a LinearLayout. Below the linearlayout I have icons (ImageViews) that when clicked hides or shows the appropriate fragment. When the app first loads, everything is fine. After I exit my app and use another app then return to my app the fragments dont hide/show when I click the icons (ImageView). WHy is this happening? Does it have something to do with the activity life cycles?
xml_layout:
<LinearLayout
android:id="#+id/Linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
onCreate()
{
ft = this.getSupportFragmentManager()
.beginTransaction();
frag1= new Frag1();
frag2= new Frag2();
ft.add(R.id.linearlayout,frag1);
ft.add(R.id.linearlayout, frag2);
ft.hide(frag1).show(frag2);
ft.commit();
icon1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ftt = MainActivity.this.getSupportFragmentManager()
.beginTransaction();
ftt.hide(frag2).show(frag1);
ftt.commit();
}
});
}
I think your problem is in this line:
ft.hide(frag2).show(frag2);
You want to hide frag1 and show frag2:
ft.hide(frag1).show(frag2);
Yes, the answer relates to the activity cycle. You need to override onCreateView and put your onClickListener inside of that. The onCreate is only getting called when the activity is first created. OnCreateView is called immediately after that, but it is also called when your activity is brought back to the front after you return from another activity.
I have one activity and multiple fragments in my app. i want to back one by one fragments when pressing back button which in all fragments.
i used this code segment but when pressing back button it comes to main activity without back one by one. Also i want to change the icon when it's comes to the main activity.(msg_alert)
btnBack.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = MainActivity.this
.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = new MainMenuLayout();
ft.replace(R.id.activity_main_content_fragment, fragment);
ft.commit();
btnBack.setVisibility(View.VISIBLE);
btnBack.setImageResource(R.drawable.msg_alert);
tvTitle.setText("Layout 0");
}
});
Lets say you are having two fragments A and B. Fragment A is is attached at the startup of activity and on any user event you navigate to fragment B by replacing the Fragment A.
1) while adding Fragment B to the activity
// Works with either the framework FragmentManager or the
// support package FragmentManager (getSupportFragmentManager).
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragmentB, "detail")
// Add this transaction to the back stack
.addToBackStack()
.commit();
2) override the onBackPressed of the activity to handle the back button press event.
#override
public void onBackPressed() {
// is there any fragment in backstack, if yes popout.
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
return;
}
super.onBackPressed();
}
this is one more option ,
in the Activity.
Fragment secondfragment= new SecondFragmnet();
#Override
public void onBackPressed() {
if(secondfragment.isVisible()){
// replace 1st fragment
}else{
// Alert dialog for Exit App
}
// you can check multiple fragments.
Hope it helps you
You have to Use addToBackStack() method while doing Transaction Between Fragments...
Read This : Implement Back Navigation for Fragments
Use Following code when you use Fragment Transaction...
String backStateName = fragment.getClass().getName(); // getting Fragment Name..
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment)
.addToBackStack(backStateName) //adding it to BackStack..
.commit();
In Fragments we dont have back navigation..
We can acheive that through replace() method.
I seen in your code that you are only replace the content frame. and so the result is backpress it comes to activity.
Also be sure that you have your mannual back button in the activity
this is test xml for activity
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back" />
<FrameLayout
android:id="#+id/activity_main_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
Use
Fragment fragment = new MainMenuLayout();
ft.replace(R.id.activity_main_content_fragment, fragment);
ft.addToBackStack(null);// TODO parameter here it tag of fragment or null or "" String
ft.commit();
For more information about fragments backstack go through this android developer refrence :-Fragment BackStack
Suppose I am creating an Android application which has a Navigation drawer and set of fragments. When user clicks on an option in the Navigation drawer the corresponding fragment is loaded. The application has only one activity (Main activity) and it has no view.
When the application is first started which fragment gets loaded into the main activity? How does the application know which fragment to be loaded first without user interaction? How to set a custom fragment to be loaded automatically when the application starts?
Thank you
You just perform the same FragmentTransaction you use to replace the fragment on user interaction and in the onCreate() method of your Activity. But you have to check if savedInstanceState is null like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.flFragmentContainer, MainFragment.newInstance());
transaction.commit();
}
}
I have a problem implementing the back navigation.
Activity A1 starts Activity A2. A2 contains a full screen fragment:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- fragment goes here -->
</RelativeLayout>
in A2's onCreate() I load the fragment F1 in the container above:
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_main);
replaceFragment(new AccountHomeFragment());
}
public void replaceFragment(Fragment f){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, f);
fragmentTransaction.addToBackStack(f.getClass().getSimpleName());
fragmentTransaction.commit();
}
And at some point the user clicks on a button and the F1 is replaced by F2. The problem is when the user clicks on the back button:
1st click: nothing happens
2nd click: goes from F2 to A1 (F1 skipped)
What I expect
1st click: F2->F1
2nd click: F1->A1
I have noticed that if I press back before F1 is replaced by F2:
1st click: F1->blank screen
2nd click: blank screen->A1
I think your problem may be caused by adding your first fragment to the backstack as well. In your onCreate you call replaceFragment which adds it automatically. Just add the fragment manually without the addToBackStack call and use the replaceFragment function for all subsequent fragment transactions.