0

I am a beginner android developer trying to make an android application. My app has a viewpager with 4 fragments. Now whenever I move from main activity (viewpager activity) to another activity and back, the main activity starts again and viewpager displays first fragment instead of the fragment which was in display by user earlier. I have provided my code below. Please help so that I can fix this issue of viewpager unnecessarily rolling back to first fragment.

public class MainActivity extends AppCompatActivity {

    private static final int RC_SIGN_IN = 123;
    private FirebaseAuth mFirebaseAuth;
    private FirebaseAuth.AuthStateListener mAuthStateListener;
    public String ADMIN_CHANNEL_ID = "ADMIN";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        final PbFragmentPagerAdapter adapter = new PbFragmentPagerAdapter(getSupportFragmentManager());
        final TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
        mFirebaseAuth = FirebaseAuth.getInstance();
        mAuthStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if(user!=null){
                    viewPager.setAdapter(adapter);
                    tabLayout.setupWithViewPager(viewPager);
                    viewPager.setOffscreenPageLimit(4);
                    adapter.fetchFragmentByPosition(viewPager, viewPager.getCurrentItem());

                }
                else{startActivityForResult(
                        AuthUI.getInstance()
                                .createSignInIntentBuilder()
                                .setAvailableProviders(Arrays.asList(
                                        new AuthUI.IdpConfig.EmailBuilder().build(),
                                        new AuthUI.IdpConfig.GoogleBuilder().build()
                                        ))
                                   .setLogo(R.drawable.ic_fui_icon_round)
                                .build(),
                        RC_SIGN_IN);
                }
            }
        };

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Create the NotificationChannel
            CharSequence name = getString(R.string.notifications_admin_channel_name);
            String description = getString(R.string.notifications_admin_channel_description);
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel mChannel = new NotificationChannel(ADMIN_CHANNEL_ID, name, importance);
            mChannel.setDescription(description);
            mChannel.enableLights(true);
            mChannel.setLightColor(R.color.colorPrimaryDark);
            mChannel.enableVibration(true);
            NotificationManager notificationManager = (NotificationManager) getSystemService(
                    NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(mChannel);
        }

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode== RC_SIGN_IN){
            if(resultCode==RESULT_OK){
                Toast.makeText(MainActivity.this, "Signed In Successfully!",Toast.LENGTH_SHORT).show();
            }
                else if (resultCode==RESULT_CANCELED){
                    finish();
                }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.sign_out_menu:
                AuthUI.getInstance().signOut(this);
                return true;
            case R.id.share_menu:
                shareApp();
                return true;
            case R.id.terms_menu:
                openTermsActivity();
                return true;
            case R.id.privacy_menu:
                openPrivacyActivity();
                return true;
            case R.id.about_menu:
                openAboutActivity();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public void openAboutActivity() {
        Intent intent = new Intent(this, AboutActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(intent);
    }
    public void openTermsActivity() {
        Intent intent = new Intent(this, TermsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(intent);
    }
    public void openPrivacyActivity() {
        Intent intent = new Intent(this, PrivacyActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(intent);
    }
    public void shareApp() {

        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT,
                "Hi, I would like to recommend the xyz app to you..);
        shareIntent.setType("text/plain");
        startActivity(shareIntent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mFirebaseAuth.addAuthStateListener(mAuthStateListener);
    }

    public class PbFragmentPagerAdapter extends SmartFragmentStatePagerAdapter {
        final int PAGE_COUNT = 4;
        private String tabTitles[] = new String[] { "Open Trades", "Past Trades", "Books", "Broker" };


        public PbFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }


        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new OpenTradesFragment();
                case 1:
                    return new PastTradesFragment();
                case 2:
                    return new BooksFragment();
                case 3:
                    return new BrokersFragment();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return PAGE_COUNT;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabTitles[position];
        }

    }

}

// below code is for pager adapter

public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
    // Sparse array to keep track of registered fragments in memory
    private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

    public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    // Register the fragment when the item is instantiated
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    // Unregister when the item is inactive
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    // Returns the fragment for the position (if instantiated)
    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }

    public Fragment fetchFragmentByPosition(ViewGroup pagerInstance, int position) {
        Fragment existingInstance = registeredFragments.get(position);
        if (existingInstance != null) {
            return existingInstance;
        } else {
            return (Fragment)instantiateItem(pagerInstance, position);
        }
    }
}

sharing XML file below:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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"
    android:layout_centerVertical="true"
    android:orientation="vertical"
    android:id="@+id/main_activity_layout"
    tools:context="in.permabull.permabull.MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabSelectedTextColor="@color/colorPrimaryDark"
        app:tabTextColor="@color/colorGrey"
        app:tabPadding="8dp"
        app:tabMode="scrollable">

    </android.support.design.widget.TabLayout>

        <TextView
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/colorLightGrey"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1">

    </android.support.v4.view.ViewPager>



</LinearLayout>
PB23
  • 5
  • 4
  • 1
    *`Android App gets relaunched`* Means your app getting crashed you need to share that Carsh log with question have look here [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this) – AskNilesh Jul 23 '18 at 06:54
  • no my app is not crashing. the activity just starts again and viewpager shows fragment 1 and not the fragment which was in view before pressing the back button or home button. – PB23 Jul 23 '18 at 06:57
  • save the viewpager value and set when activity again resume. – sushildlh Jul 23 '18 at 06:58
  • can you please provide some code.. i am new to android.. so need some help please.. – PB23 Jul 23 '18 at 06:59
  • Would you please share the code that you declared `MainActivity` at manifest? – salmanseifian Jul 23 '18 at 07:08
  • is FirebaseAuth is any class ? @PB23 – Rajshree Tiwari Jul 26 '18 at 11:55
  • @RajshreeTiwari It is a backend user authentication(login/logout) service by firebase. i dont have code for that.. just using their API. – PB23 Jul 26 '18 at 12:00
  • shared XML file of main activity – PB23 Jul 26 '18 at 12:06
  • @PB23 Ii is working fine, what issue you are facing, can you share your test apk file – Rajshree Tiwari Jul 26 '18 at 12:26
  • @RajshreeTiwari MainActivity(which contains ViewPager) is working fine when i switch on "Don't Keep Activities" in Developer Settings of my mobile phone (SDK level 21). Viewpager opens the fragment where i left it before leaving app. What does it mean? – PB23 Aug 03 '18 at 09:13

1 Answers1

0

As expected it was a simple problem.. solved it (using onPageSelected) as follows:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                        @Override
                        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                        }

                        @Override
                        public void onPageSelected(int position) {
                            tabPosition=position;
                        }

                        @Override
                        public void onPageScrollStateChanged(int state) {

                        }

where tabPosition is a global int variable that helps to store the fragment(tab) number on which the viewpager is when back/home button is pressed.

PB23
  • 5
  • 4