Keep focus of item BottomNavigationView clicked after rotating screen

1

I have a problem when I rotate the screen.

I have the following structure:

  • A HomeActivity that handles the clicks in the BottomNavigationView (there are 4 items)
  • Each BottomNavigationView item loads a Fragment with different data

However, when I rotate the screen in any of them (item), the Fragment loses focus and the Fragment of position 0 (the first) is displayed for the user. What I want to do is: keep the Fragment selected when the user rotates the screen in any of them.

How can I resolve this? I took a look at the Fragments Lifecycle, but I can not figure out how to resolve it.

HomeActivity onCreate

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
            .setDefaultFontPath("fonts/futura.ttf")
            .setFontAttrId(R.attr.fontPath)
            .build());

    final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.frame_layout, AgendaFragment.newInstance());
    transaction.commit();

    mBottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation_bottom);

    mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment selectedFragment = null;
            switch (item.getItemId()) {
                case R.id.navigation_agenda:
                    selectedFragment = AgendaFragment.newInstance();
                    toolbar.setTitle(getString(R.string.txt_nossa_agenda));
                    break;
                case R.id.navigation_palestras:
                    selectedFragment = PalestrasFragment.newInstance();
                    toolbar.setTitle(getString(R.string.txt_nossas_palestras));
                    break;
                case R.id.navigation_minicursos:
                    selectedFragment = MinicursosFragment.newInstance();
                    toolbar.setTitle(getString(R.string.txt_nossos_minicursos));
                    break;
                case R.id.navigation_workshops:
                    selectedFragment = WorkshopsFragment.newInstance();
                    toolbar.setTitle(getString(R.string.txt_nossos_workshops));
                    break;
            }
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.frame_layout, selectedFragment);
            transaction.commit();
            return true;
        }
    });
}

onCreate / onCreateView of the Fragment that loses focus (eg: FractionFragment

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_palestras, container, false);

    mArrayListPalestrantes = new ArrayList<>();
    mRecyclerViewPalestrantes = view.findViewById(R.id.recycler_view_palestras);
    mRecyclerViewPalestrantes.setLayoutManager(new LinearLayoutManager(getContext()));

    carregaLista();

    PalestranteAdapter adapter = new PalestranteAdapter(mArrayListPalestrantes);
    mRecyclerViewPalestrantes.setAdapter(adapter);

    return view;
}

OnCreate / onCreateView of Fragment that appears when rotating screen

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_agenda, container, false);

    ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
    setupViewPager(viewPager);
    TabLayout tabs = (TabLayout) view.findViewById(R.id.result_tabs);
    tabs.setupWithViewPager(viewPager);

    String weekDay;
    SimpleDateFormat dayFormat = new SimpleDateFormat("EEEE", Locale.US);

    Calendar calendar = Calendar.getInstance();
    weekDay = dayFormat.format(calendar.getTime());
    Log.i("dia", "Hoje é: " + weekDay);

    switch (weekDay){
        case "Monday":
            viewPager.setCurrentItem(0);
            break;
        case "Tuesday":
            viewPager.setCurrentItem(1);
            break;
        case "Wednesday":
            viewPager.setCurrentItem(2);
            break;
        case "Thursday":
            viewPager.setCurrentItem(3);
            break;
        case "Friday":
            viewPager.setCurrentItem(4);
            break;
        case "Saturday":
            viewPager.setCurrentItem(0);
            break;
        case "Sunday":
            viewPager.setCurrentItem(0);
            break;
        default:
            viewPager.setCurrentItem(0);
    }

    return view;
}

Images Left: Fragment selected - Right: Main Fragment is shown and selected Fragment loses focus

    
asked by anonymous 23.08.2017 / 14:13

2 answers

1

Try first to save the id of the selected BottomNavigationView in onSaveInstanceState() to your HomeActivity

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    // Salva o id do menu do fragment selecionado
    int idMenu = bottomNavigationView.setSelectedItemId(R.id.item_id);
    savedInstanceState.putInt("idMenu", idMenu);

    super.onSaveInstanceState(savedInstanceState);
}

And then recover on onCreate() :

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Chama a superclass primeiro

// Verifica se está criando uma instância previamente destruída
if (savedInstanceState != null) {
    // Restaura o id do menu e o seleciona
   int idMenu = savedInstanceState.getInt("idMenu");
   bottomNavigationView.setSelectedItemId(idMenu);

} else {
    // Caso seja uma nova instância, inicializa normalmente
}
}

More information about the onSaveInstanceState .

    
23.08.2017 / 15:29
0

Every time the cell phone screen is rotated its Activity is destroyed and then restarted. If you want data not to be lost during this rotation you will need to save it using the lifecycle methods.

Tip: Save the data you need to save to onDestroy () and retrieve it in onCreate () and adapt the view to mount according to the retrieved data.

See Saving states persistently

    
23.08.2017 / 14:55