// Here is the adapter for viewpager
public void setupViewPager(){
pageAdapter = new PageAdapter(getSupportFragmentManager());
pageAdapter.addFragment(FragmentDesigns.newInstance(), "INDIAFILINGS");
icfo = ICFO.newInstance();
pageAdapter.addFragment(icfo, "iCFO PLATFORM");
viewPager.setAdapter(pageAdapter);
tabLayout.setupWithViewPager(viewPager);
// here code to set particular item in viewpager
int pageRedirect;
pageRedirect=CommonClass.getPageRedirect();
try {
if(pageRedirect!=0){
viewPager.setCurrentItem(1);
}
}catch (Exception e){
e.printStackTrace();
}
}
I am implementing viewpager with two fragments.In second Fragment i have list of data if user selects any item from a list it will redirect to another activity.If user does onbackPress in activity i want to set viewpager second fragment as a current fragment
Note:The issue is when i do onbackPress the application is getting close
#Override
public void onBackPressed() {
if (viewPager.getCurrentItem() != 0) {
viewPager.setCurrentItem(secondViewpagerItemPostion,false);
}else{
super.onBackPressed();
}
}
Store your current position of view pager in sharepref and check it if not null then viewpager.setCurrentItem(shareprefPosition);
override the onBackPressed method in your second activity so that system default behaviour does not happen
#Override
public void onBackPressed() {
Intent firstintent = new Intent(context,Firstactivity.class);
firstintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(firstintent);
}
This will open the first activity, close the second activity and deliver the result in the onNewIntent of the first activity
In your first activity override onNewIntent so that the back press result is found
#Override
protected void onNewIntent(Intent intent) {
yourvp.setCurrentItem(positionyouneed);
}
This should do the trick for you
Related
So I have bottom navigation bar with 4 fragments for each tab, and inside each one I call an API request to fetch some data, but the problem is each time I press any tab of the bar, at least two of the fragments gets created and they call their own method and by extension they fires the API request..! I just want the fragment that I select to be instantiated.!
I know the adapter behaves like this to pre-render the fragment to ensure better transaction between tabs and whatnot..! but I really can't afford to call multiple api calls with each select..!
Adapter
public class My_PagerAdapter extends FragmentPagerAdapter {
// I've tried FragmentStatePagerAdapter but same thing
public My_PagerAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
new MyFragment_1();
case 1:
new MyFragment_2();
case 2:
new MyFragment_3();
case 3:
new MyFragment_4();
}
}
#Override
public int getCount() {
return 4;
}
}
Edit
This how I call the adapter..
ViewPager viewPager = main.findViewById(R.id.vp);
viewPager.setOffscreenPageLimit(1);
viewPager.setAdapter(new My_PagerAdapter (getChildFragmentManager()));
navigationTabBar.setModels(models); // just UI stuff for each tab offered by the bottom navigation bar library,
navigationTabBar.setViewPager(viewPager);
I ran into this same exact issue on a project that I'm working on
The solution for me was to add the API calls on the OnResume method in each fragment.
That way they will only be triggered when the fragment is fully visible.
Check out the fragment lifecycle
Ok this is exactly an issue that i faced. The solution i have does not stop the viewpager from creating the fragments but it will stop the calls to network api.
Heres the gist:
1) Create an interface
public interface ViewPagerLifeCycleManagerInterface {
void onResumeAndShowFragment();
void onPauseAndHideFragment();
//void refreshFragment();
}
2) modify your FragmentPagerAdapter to override the onInstantiateItem method
Here each Fragment will have a weakReference declared inside the Adapter class in order to store a reference to the fragments created
#Override
public Object instantiateItem(ViewGroup container, int position){
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
switch (position){
case 0:
xyzWeakReference=null;
xyzFragmentWeakReference=new WeakReference<>((xyz)createdFragment);
break;
case 1:
xyz1WeakReference=null;
xyz1WeakReference=new WeakReference<>((xyz1WeakReference)createdFragment);
break;
}
return createdFragment;
};
3) Inside the FragmentPagerAdapter, add the following method in order to fetch the weak reference of the fragment in picture
public Fragment getFragmentAtGivenPosition(int i){
switch (i){
case 0:
if(xyzFragmentWeakReference == null){
return null;
}
return xyzFragmentWeakReference.get();
case 1:
if(xyz1FragmentWeakReference == null){
return null;
}
return xyz1FragmentWeakReference.get();
}
}
4) Now in the activity where the TabLayout is created and the view pager instantiated, attach a listener to the TabLayout for listening to tab changes
tabLayout_bookmarks.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(final TabLayout.Tab tab) {
//let the instantiateItem have some time to be called by the adapter
currentFragmentIndex = tab.getPosition();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ViewPagerLifeCycleManagerInterface currentFragment = (ViewPagerLifeCycleManagerInterface)btca.getFragmentAtGivenPosition(tab.getPosition());
if(currentFragment!=null){
currentFragment.onResumeAndShowFragment();
}else{
//Log.d("FragmentCreate","Current fragment is null and fucked up in adapter");
//if it is null ... that means the adapter hasn't yet called instantiate item ... this internally calls get item any way
//.....
//This shouldn't really hit but in case it does ... keep a handler in order to ensure that everything is created
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ViewPagerLifeCycleManagerInterface localFragment = (ViewPagerLifeCycleManagerInterface)btca.getItem(tab.getPosition());
//getItem never returns a null fragment unless supplied a horrendous value for position
//by the time these 50 ms pass, the instantiate item should surely have been called
//else it will be an empty space ... no crash though
localFragment.onResumeAndShowFragment();
}
},50);
}
}
},100);
}
#Override
public void onTabUnselected(final TabLayout.Tab tab) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ViewPagerLifeCycleManagerInterface currentFragment = (ViewPagerLifeCycleManagerInterface)btca.getFragmentAtGivenPosition(tab.getPosition());
if(currentFragment!=null){
currentFragment.onPauseAndHideFragment();
}else{
//Log.d("FragmentCreateTab","the fucking fragment was null");
//if it is null ... that means the adapter hasn't yet called instantiate item ... this internally calls get item any way
//.....
//This shouldn't really hit but in case it does ... keep a handler in order to ensure that everything is created
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ViewPagerLifeCycleManagerInterface localFragment = (ViewPagerLifeCycleManagerInterface)btca.getItem(tab.getPosition());
//getItem never returns a null fragment unless supplied a horrendous value for position
//by the time these 50 ms pass, the instantiate item should surely have been called
//else it will be an empty space ... no crash though
localFragment.onPauseAndHideFragment();
}
},50);
}
}
},100);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
//do nothing
}
});
5) In each of the Fragments inside the Viewpager, implement the Interface we created in step 1 and override the methods.
Create a boolean variable in each fragment amIVisible... This will help decide when the fragment is visible and when it can call the network api
a) here for the first fragment in viewpager, i.e at 0 index, the network api call has to happen immediately after the view gets created. This fragment is obviously visible by default. This is written inside onCreateView method
if(dataList!=null && dataList.size()==0) {
if (savedInstanceState==null) {
//your api call to load from net
} else {
if (savedInstanceState.getBoolean("savedState")) {
//If you have saved data in state save, load it here
} else {
//only fire the async if the current fragment is the one visible, else the onResumeAndShowFragment will trigger the same async when it becomes visible
if (savedInstanceState.getBoolean("amIVisible")) {
//Load data from net
}
}
}
}
The other methods are as follows for the first fragment
#Override
public void onResumeAndShowFragment() {
amIVisible=true;
if(dataList!=null && dataList.size()==0){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Load data from net if data was not found,
//This basically means auto refresh when user scrolls back and the fragment had no data
}
},400);
}
}
#Override
public void onPauseAndHideFragment() {
amIVisible=false;
}
Here i have overriden onSaveInstanceState method and saved the value of amIVisible and savedState is a boolean which indicates if the list has at least 1 item or not.
b) For the other fragments, Data will be loaded by the following process
if(savedInstance!=null){
if (savedInstance.getBoolean("savedState")) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//load data from saved State
}
},100);
} else {
//only fire the async if the current fragment is the one visible, else the onResumeAndShowFragment will trigger the same async when it becomes visible
if (savedInstance.getBoolean("amIVisible")) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//load data from net
}
},100);
}
}
}
The interface methods are the same for the other fragments.
This is pretty complicated but does the job. The weak references inside the adapter even allow garbage collection and avoid context leaks.
I have a FrameLayout and put there some fragments by click on button, next click should remove fragment from FrameLayout, I do this by removeAllViews() (FrameLayout is in another Fragment so translaction method is in Activity).
I need to do some action when removeAllViews() starts and have to do it in Fragment class but something goes wrong.
I tried:
OnDestroy()
OnDestroyView()
OnPause()
in Fragment class
but it works like:
put Fragment in FrameLayout (from Activity)
use removeAllViews() (from Activity)
there is no Fragment in FrameLayout (is clear) but nothing else happens and methods are not working
put new Fragment in FrameLayout (from Activity) - now all methods (OnDestroy() from Fragment class) works (probably it's real time to destroy old fragment)
How is it possible to 'get moment' when Fragment is not exists for user? I want to send some information to server if user hides Fragment.
#Edit3
code from method from Activity where I want to make translaction
public void showProductsList(String productType,int containerID){
List<String> prodNames = new ArrayList<String>();
List<Long> prodIds = new ArrayList<Long>();
DatabaseDAOProdProtein dao = new DatabaseDAOProdProtein(getApplicationContext());
dao.open();
List<DatabaseProduct> productList = dao.getAllProducts();
for(int i=0;i<productList.size();i++){
prodNames.add(productList.get(i).getName());
prodIds.add(productList.get(i).getId());
}
dao.close();
ProductsList productsList = new ProductsList(productType,prodNames,prodIds);
productsList.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
Toast.makeText(getApplicationContext(),"action1 " ,Toast.LENGTH_LONG).show();
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
Toast.makeText(getApplicationContext(),"action2 " ,Toast.LENGTH_LONG).show();
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
Toast.makeText(getApplicationContext(),"action3 " ,Toast.LENGTH_LONG).show();
}
}
});
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(containerID, productsList).commit();
}
I used this method in another Fragment by:
((MainActivity) getContext()).showProductsList("carb", carbContainer.getId());
there is an error:
Error:(560, 21) error: cannot find symbol method setOnSystemUiVisibilityChangeListener(<anonymous OnSystemUiVisibilityChangeListener>)
You say:
"How is it possible to 'get moment' when Fragment is not exists for
user? I want to send some information to server if user hides
Fragment."
I now know you did not mean "hide", so just use the OnDestroy() method.
Try this to trigger the "hide"
View topLevelLayout = findViewById(R.id.top_layout);
topLevelLayout.setVisibility(View.INVISIBLE);
You cannot go into stopped state while Fragment (Activity) is visible. Android destroying activities, killing processes
The best way to make sure something runs via a view is to run it via a post:
topLevelLayout.post(new Runnable()
{
#Override
public void run()
{
topLevelLayout.removeAllViews();
}
}
To get notified of system UI visibility changes, register an View.OnSystemUiVisibilityChangeListener to your view (fragment).
https://developer.android.com/training/system-ui/visibility.html
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(getContext(),"action0 " ,Toast.LENGTH_LONG).show();
Fragment your_frag = new ProductsList(productType,prodNames,prodIds);
getSupportFragmentManager().beginTransaction().replace(containerID,your_frag).commit();
getSupportFragmentManager().executePendingTransactions();//make sure onCreateView has executed
your_frag.getRootView().setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
Toast.makeText(getContext(),"action1 " ,Toast.LENGTH_LONG).show();
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
Toast.makeText(getContext(),"action2 " ,Toast.LENGTH_LONG).show();
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
Toast.makeText(getContext(),"action3 " ,Toast.LENGTH_LONG).show();
}
}
});
}
A typical fragment looks like this:
public class HomeFragment extends Fragment {
View mRootView = null;
public HomeFragment(){}//null constructor
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_home, container, false);
return mRootView ;
}
public View getRootView ()
{
return mRootView;
}
}
I have an activity that has 3 fragments on it with Tabs, one of them is called "TaskFragment".
In my main Activity i only load the fragments.
In TaskFragment i have a RecyclerView that is working fine and is showing the items as intended.
The problem comes, when i insert data using a DialogFragment, because it does insert data (i am using DbFlow ORM), but it does not (of course) refresh the adapter since it is in the TaskFragment fragment inside the DetailMainActivity activity as i said.
I have tried to use onResume() and onPause() in order to refresh the adapter, but they are never called since the activity does not get paused or in onresume for a DialogFragment.
I have tried aswell to use an interface, but it does not work and i have searched all over stackoverflow and google with no luck.
I leave here some of my code for you to understand better:
DetailMainActivity.java
Here in the onClick interface i show the DialogFragment to the user to input the information.
FragmentManager fm = getSupportFragmentManager();
AddSimpleTask sptask = new AddSimpleTask();
sptask.show(fm, "tag");
TaskFragment.java
In this fragment i have my RecyclerView
private void setupRecyclerView() {
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (DetailMainActivity.FAB_Status) {
DetailMainActivity.hideFAB();
DetailMainActivity.FAB_Status = false;
}
return false;
}
});
}
private void setupAdapter() {
adapter = new DetailMainTaskAdapter(simpleTaskList, this);
}
AddSimpleTask
And this is my DialogFragment. I have set a setOnShowListener() in order to avoid the DialogFragment to get dismiss early.
#Override
public void onShow(DialogInterface dialogInterface) {
final AlertDialog dialog =(AlertDialog) getDialog();
if (dialog != null){
Button positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
Button negativeButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
positiveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mEditTextName.getText().toString().trim().isEmpty() ||
mEditTextContent.getText().toString().trim().isEmpty() ) {
if (mEditTextName.getText().toString().trim().isEmpty()) {
mEditTextName.setError("Can not be empty");
}
if (mEditTextContent.getText().toString().trim().isEmpty()) {
mEditTextContent.setError("Can not be empty");
}
}else {
presenter.beingInsertion(mEditTextName.getText().toString().trim(), mEditTextContent.getText().toString().trim()
, foreignId);
}
}
});
negativeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
}
}
If the insert is successfully achieved the onInsertSuccess method is called (i am using MVP)
#Override
public void onInsertSuccess() {
Snackbar.make(getActivity().findViewById(R.id.containerMainDetail), "Actividad agregada", Snackbar.LENGTH_SHORT).show();
dismiss();
}
I have called adapter.notifyDataSetChanged() in many places, and i also tried with a custom interface, but i can not make this work.
Sorry for the long post, but thanks in advance for your help.
There are some errors in your statement but I'll get to that later. notifyDataSetChanged() only notifies the adapter that the underlying list (or array) has changed. The implication is that you first need to requery your database and obtain the new list before calling notifyDataSetChanged() on the adapter else there is no point as the underlying list will still be the same and it will not update the adapter.
The correct way of calling this will be through your custom listener interface and not in the onPause()/onResume() callbacks as there is the possibility that the user does not enter a value and hence you will unnecessarily be querying the database. In your custom listener interface implementation, first update the list with the new data from the DB and then notify the adapter.
Which leads to the error in assumption that onPause()/onResume() callbacks do not happen when your Activity is covered by a DialogFragment - this is incorrect. The moment the activity view is even partially covered, the onPause() callback is triggered.
I have main activity and 2 fragments on it, fragment1 call fragment2
When I am clicking the back button from the built in android buttons it call the onBackPressed function that I overrided in the main activity and exit me from the app.
I want that when I click back on the fragment 2 the onBackPressed of the main activity will not called and it will back me to fragment 1.
The back button of the action bar works well (I think it mean that the backstack is ok).
I tried to do:
getActivity().getSupportFragmentManager().beginTransaction().addToBackStack("Messages");
on the fragment 2
And tried to add
getSupportFragmentManager().popBackStack();
to the onBackPressed() of the main activity
It dosen't did nothing
Thank you
EDIT:
I am trying to do
public void onBackPressed() {
// getSupportFragmentManager().popBackStack();
android.support.v4.app.Fragment fragment2 = getSupportFragmentManager().findFragmentByTag(null);
if (fragment2 != null && fragment2.isVisible()) {
getSupportFragmentManager().popBackStack();
return;
}
and before any show
getSupportFragmentManager().beginTransaction().addToBackStack(null).commit();
tr.show(Fragment2);
but got null on the findFragment(null)
EDIT:
I checked getSupportFragmentManager().beginTransaction().mTail.fragment and saw that the value is the Fragment 1 that I want to be showed, but when I do getSupportFragmentManager().popBackStack(); it dosen't nothing.
Override onBackPressed() in Main activity.
Check the currently displayed fragment, if fragment2 is displayed, then pop back stack.
example:
#Override
public void onBackPressed() {
Fragment fragment2 = getFragmentManager().findFragmentByTag("tag");
if (fragment2 != null && fragment2.isVisible()) {
getFragmentManager().popBackStack();
} else {
finish();
}
}
just use below way; in your Activity check this
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
Fragment fragment = getSupportFragmentManager().findFragmentByTag("SecondFragment");
if (fragment instanceof SecondFragment) {
// show first fragment
}else{
// finish();
}
}
i have used findFragmentByTag, you can also use findFragmentById
i agree with #Minhtdh comment but it only applicable if you replace one over other
Before calling fragment2.show() in the MainActivity, add the fragmnet transaction to backstack. There is no need to override onBackPressed().By default android implements the same functionality for you.
simple working code.
to get back to 1st fargment.
yourviewvariable.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
Sorry that I miss typed, I mean method onBackPressed.
But for your case, because you use FragmentTransition.show(), it will not add the fragment to backstack and popBackStack won't work. So I think you should try this:
1. don't called getSupportFragmentManager().beginTransaction().addToBackStack(null).commit(); because it add an unnecessary backstack.
2. don't store the "tr" variable as global variable, and you also need call commit() to end the transaction:
Fragment2.setTag("fragment2");
getSupportFragmentManager().beginTransaction().show(Fragment2).commit();
3. in onBackPressed():
android.support.v4.app.Fragment fragment2 = getSupportFragmentManager().findFragmentByTag("fragment2");
if (fragment2 != null && fragment2.isVisible()) {
getSupportFragmentManager().beginTransaction().hide(fragment2).commit();
return;
} else {
super.onBackPressed();
}
Hope this help.
I have three activities: First, Second and Third. I used this method in Second activity:
public void onBackPressed() {
super.onBackPressed();
finish();
}
and this on Third activity:
public void onBackPressed() {
super.onBackPressed();
Intent i = new Intent(Third.this, Second.class);
startActivity(i);
finish();
}
The problem is when I press back button after coming from the Third activity, I am going into First activity instead of finish(). I am successfully exiting the application when I click back button right after coming from first activity but not after coming from Third activity.
How to solve this problem?
EDIT: Thanks for the answers guys,the answer of "Ved Prakash" solved the problem for me.But i have a weird problem now.When i press back button the app is successfully exiting but the app which i minimized to Recent Apps button is coming on to the screen and exiting.For example,if i have opened Setting app before opening my app,when i press back button,my app is exiting and immediately Settings app is also opening and exiting itself.What might be the problem?
Your problem is that you don't seem to understand how Activities work. The finish() function ends the current Activity, and then you receive the previous Activity from the backstack.
My recommendation is that you should use a single Activity, and hold Fragments inside it. If you want it so that pressing the Back button ends the application at any screen that is displayed, you could do the following:
Activity XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/initial_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Activity that holds the Fragments:
public class InitialActivity extends FragmentActivity implements ReplaceWith
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_initial);
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
if (savedInstanceState == null)
{
getSupportFragmentManager().beginTransaction().add(R.id.initial_container, new FirstFragment()).commit();
}
}
#Override
public void replaceWith(Fragment fragment)
{
getSupportFragmentManager().beginTransaction().replace(R.id.initial_container, fragment).commit();
}
}
Example for a Fragment:
public class FirstFragment extends Fragment implements View.OnClickListener
{
private ReplaceWith activity_replaceWith;
private ImageView exampleImage;
public FirstFragment()
{
super();
}
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
activity_replaceWith = (ReplaceWith) activity;
}
catch (ClassCastException e)
{
Log.e(getClass().getSimpleName(), "Activity of " + getClass().getSimpleName() + "must implement ReplaceWith interface!", e);
throw e;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
exampleImage = (ImageView) rootView.findViewById(R.id.fragment_first_example_image);
exampleImage.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v)
{
if(v == exampleImage)
{
activity_replaceWith.replaceWith(new SecondFragment());
//please note that this should be done only if you are planning
//only on single-screen applications
//with no other layouts based on orientation or size
//otherwise, the Activity needs to be responsible for this, not the Fragment
}
}
}
This way, when you press the Back button, your application would end from any displayed screen.
Ok your code is wrong.
If you will look at activity source, you see that activity.onBackPressed() is calling finish(). So if call super.onBackPressed() you don't need to call finish.
Finish() is not stopping your application, it's stopping current activity.
Your code on third activity very strange. You are trying to stop activity and start another same activity.
What exactly you want to achieve?
If you want to exit application from your third activity, you need to clear your backstack. But I think you have problem with structure of your app.
Ok. then you should finish your first activity when you go to second activity like this(If you are using intent for that):
Intent it=new Intent(FirstActivity.this,SecondActivity.class);
finish();
startactivity(it);
and same for Second Activity:
Intent it=new Intent(SecondActivity.this,ThirdActivity.class);
finish();
startactivity(it);
this done your work...when you are in third activity the above activities are finished..
and when you press backButton you will be exit from application..
Good luck.
You can use -
public static final int FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
And here is how -
When the user wishes to exit all open activities, they should press a button which loads the first Activity that runs when your app starts, in my case "MainActivity".
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
The above code clears all the activities except for LoginActivity. LoginActivity is the first activity that is brought up when the user runs the program. Then put this code inside the LoginActivity's onCreate, to signal when it should self destruct when the 'Exit' message is passed.
if (getIntent().getBooleanExtra("EXIT", false)) {
finish();
}
This explanation part is also introduced at exit-an-android-app.