1.4 Настройка MainActivity

Теперь осталось реализовать MainActivity. При использовании фрагментов, большая часть логики ушла из MainActivity в отдельные фрагменты. В данном случае, нам необходимо только добавить фрагмент ContactsFragment при старте Activity, а также запрограммировать работу кнопки "назад".

Сначала реализуем добавление нового фрагмента при старте Activity.

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setWindow();

        getSupportFragmentManager()
                .beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.container, ContactsFragment.class, null)
                .addToBackStack("main")
                .commit();
    }
}

Обратите внимание, что мы также вызываем метод setReorderingAllowed(true) и addToBackStack(), как и при добавлении фрагмента AddContactFragment.

Реализация кнопки "назад"

Теперь необходимо реализовать работу кнопки "назад". Для нашего приложения логика работы кнопки "назад" должна быть следующая: если мы сейчас на экране AddContactFragment, то при нажатии "назад" на экране должен появится фрагмент ContactsFragment. Если сейчас на экране ContactsFragment, то при нажатии "назад" мы должны "выйти из приложения" (приложение будет свернуто в background). Схематично это выглядит так

Для этого мы используем такую возможность менеджера фрагментов как backstack (стек фрагментов). Он позволяет сохранить последовательность добавления фрагментов и при нажатии кнопки "назад" мы извлекаем из вершины backstack'а видимый фрагмент и показываем предыдущий фрагмент (логика работы стека фрагментов очень сильно напоминает логику работы стека activity).

В нашем случае, в стеке фрагментов всегда будет, как минимум, один фрагмент (ContactsFragment), а максимум - два фрагмента (ContactsFragment + AddContactFragment). Логика работы кнопки "назад" следующая: если в стеке больше 1 фрагмента (сейчас виден фрагмент добавления контакта), то при нажатии кнопки "назад", видимый фрагмент из стека извлекается (будет показан фрагмент списка контактов). Если же в стеке 1 фрагмент (сейчас виден фрагмент списка контактов), то при нажатии "назад", мы закрываем activity.

MainActivity.java
public class MainActivity extends AppCompatActivity {

    ...

    @Override
    public void onBackPressed(){
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
        } else {
            finish();
        }
    }
}

Полный код класса MainActivity выглядит следующим образом

MainActivity.java
public class MainActivity extends AppCompatActivity {

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

        getSupportFragmentManager()
                .beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.container, ContactsFragment.class, null)
                .addToBackStack("main")
                .commit();
    }

    @Override
    public void onBackPressed(){
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
        } else {
            finish();
        }
    }

    private void setWindow() {
        // Метод устанавливает StatusBar в цвет фона
        Window window = this.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(getColor(R.color.activity_background));

        View decor = getWindow().getDecorView();
        decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    }

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static final String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    public void verifyStoragePermissions() {
        // Проверяем наличие разрешения на запись во внешнее хранилище
        int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // Запрашиваем разрешение у пользователя
            ActivityCompat.requestPermissions(
                    this,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
}

Last updated