BottomNavigationView и Fragment. Как сохранить состояние?

334
25 июля 2022, 01:10

Есть BottomNavigationView и 3 Fragment'а. Фрагмент "Home" содержит ScrollView. При переключении на другие фрагменты, и возвращаясь, состояние сбрасывается к начальному. Т.е. если проскролить до конца, а затем вернуться в фрагмент "Home", ScrollView будет отображаться с самого начала. Как сохранить состояние?

MainActivity

public class MainActivity extends AppCompatActivity {
    BottomNavigationView mainBottomNavigation;
    Fragment homeFragment;
    Fragment favouriteFragment;
    Fragment musicFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainBottomNavigation = findViewById(R.id.bottomNavigationView);
        homeFragment = new HomeFragment();
        favouriteFragment = new FavouriteFragment();
        musicFragment = new MusicFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.containerMain, homeFragment).commit();
        mainBottomNavigation.setOnNavigationItemSelectedListener(item -> {
            if (item.getItemId() == R.id.homeItem) {
                showFragment(homeFragment);
            } else if (item.getItemId() == R.id.favourite) {
                showFragment(favouriteFragment);
            } else if (item.getItemId() == R.id.music) {
                showFragment(musicFragment);
            }
            return true;
        });
    }
    private void showFragment(Fragment currentFragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.containerMain, currentFragment).commit();
    }
}

HomeFragment

public class HomeFragment extends Fragment {
    private int count = 0;
    TextView textView;
    boolean isCreated = false;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.home_fragment, container, false);
        textView = view.findViewById(R.id.homeTextView);
        Button increment = view.findViewById(R.id.increment);
        if (!isCreated) {
            textView.setText("Home Fragment");
        } else {
            textView.setText(String.valueOf(count));
        }
        increment.setOnClickListener(v -> {
            count++;
            textView.setText(count + " ");
        });
        return view;
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        isCreated = true;
    }
}

FavouriteFragment

public class FavouriteFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.favourite_fragment, container, false);
    }
}

MusicFragment

public class MusicFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.music_fragment, container, false);
    }
}
Answer 1

Для ваших целей я думаю подойдёт SharedPreferences. Введите какие-то порядковые номера для ваших фрагментов например, или любую другую идентификацию чтобы можно их было как-то различать. Запись переменной я бы советовал осуществлять в селекторе нижнего меню, для этого вынесем сохранение в отдельный метод:

private void savePos(Integer pos){
    SharedPreferences mSettings = getSharedPreferences("app_data", Context.MODE_PRIVATE);
    Editor editor = mSettings.edit();
    editor.putInt("frag_id", pos); // например будем писать порядковый номер
    editor.apply();
}

Который будем вызывать тут:

mainBottomNavigation.setOnNavigationItemSelectedListener(item -> {
            if (item.getItemId() == R.id.homeItem) {
                savePos(0);
                showFragment(homeFragment);
            } else if (item.getItemId() == R.id.favourite) {
                showFragment(favouriteFragment);
            } else if (item.getItemId() == R.id.music) {
                showFragment(musicFragment);
            }
            return true;
        });

и дальше в методе onCreate вашей активности считываем данную переменную:

Integer fragId = mSettings.getInt("frag_id", 0);

После получения кидаем это все в какой-то switch-case например и делаем выбор нижнего меню. Вот туториал по работе с SP и документация

READ ALSO
Проблема с итерацией в цикле

Проблема с итерацией в цикле

Есть некоторая коллекция(исходник: Проблема с удалением переменных классов потомков):

363
Динамический выпадающий список с данными из mysql на php

Динамический выпадающий список с данными из mysql на php

Помогите реализовать задачу, иметься таблица в базе данных

393
Зачем на нужны join если есть where?

Зачем на нужны join если есть where?

Учу sql заново, и у меня возник вопрос зачем вообще нужны джоиныОбъеденить таблицы ведь можно с помощью фореина и праймари ключей в таблицах...

298
Qt, C++ захват ссылки в асинхронной лямбде

Qt, C++ захват ссылки в асинхронной лямбде

Насколько безопасно так делать?

401