Keep the item focus Bottomnavigationview clicked after rotate screen

Asked

Viewed 92 times

1

I have a problem when I rotate the screen.

I have the following structure:

  • A Homeactivity that handles clicks on Bottomnavigationview (there are 4 items)
  • Each Bottomnavigationview item loads a Fragment with separate data

However, when I rotate the screen on any of them (item), the Fragment loses focus and the Fragment of position 0 (the first) is displayed to 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 fix this? I took a look at the Fragments Life Cycle, but I can’t figure out how to fix it.

onCreate from Homeactivity

@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 from Fragment that loses focus (Ex: Speaker fragment

@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 from Fragment which is displayed when rotate 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;
}

Imagery Left: Fragment selected - Right: Main fragment is shown and the selected fragment loses focus inserir a descrição da imagem aqui

  • 1

    You have two options, either lock the screen when rotate or you save the state. See this answer to block: https://answall.com/questions/193429/deixar-app-somente-em-modo-retrato/193475#193475 See this answer to how it can be saved: https://answall.com/a/168412/35406

2 answers

1

First try saving the selected Bottomnavigationview id in onSaveInstanceState() in 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 in the 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 on the onSaveInstanceState.

0

Every time the mobile screen is rotated your Activity is destroyed and then restarted. If you want the data not to be lost during this rotation you will need to save them using life cycle methods.

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

See about Saving states persistently

Browser other questions tagged

You are not signed in. Login or sign up in order to post.