Как я могу сохранить фрагменты и их данные об изменении ориентации с помощью BottomNavigationView - PullRequest
0 голосов
/ 27 января 2019

После нескольких уроков на YouTube (например, https://www.youtube.com/watch?v=tPV8xA7m-iw) я смог создать Activity с BottomNavigationView, который переключается между тремя различными фрагментами.

Я не уверен, что этолучший способ для достижения моих целей. Мне нужны три экрана, на одном из которых (ReportFragment) будут введены данные, которые я хочу оставить, когда пользователь переключается между фрагментами.

У меня также возникают трудностисохранение данных фрагмента при изменении ориентации.

Вот один из кодов фрагмента, который я реализовал в onSavedInstanceState для вызова данных, введенных пользователем, и, кажется, работает нормально:

public class ReportFragment extends Fragment {

EditText textCheck;
EditText textCheck2;
EditText textCheck3;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_report, null);

    textCheck = view.findViewById(R.id.editName);
    textCheck2 = view.findViewById(R.id.editHaz);
    textCheck3 = view.findViewById(R.id.editNotes);

    if (savedInstanceState != null) {
       textCheck.setText(savedInstanceState.getString("name"));
       textCheck2.setText(savedInstanceState.getString("haz"));
       textCheck3.setText(savedInstanceState.getString("notes"));
    }
    return view;
}


@Override
public void onSaveInstanceState (Bundle outState)
{
    super.onSaveInstanceState(outState);

    outState.putString("name", textCheck.getText().toString());
    outState.putString("haz",  textCheck2.getText().toString());
    outState.putString("notes",  textCheck3.getText().toString());
}

}

Вот код активности:

public class FeedActivity extends AppCompatActivity
        implements BottomNavigationView.OnNavigationItemSelectedListener {

    private HomeFragement frag1;
    private ReportFragment frag2;
    private MapFragement frag3;


    BottomNavigationView navigation;

    private static final String TAG = "FeedActivity";

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

        navigation = findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(this);
        if (savedInstanceState == null) {

            frag1 = new HomeFragement();
            frag2 = new ReportFragment();
            frag3 = new MapFragement();

            loadFragment(frag1);
        }
    }


    private boolean loadFragment(Fragment fragment) {
        if (fragment != null) {

            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragment_container, fragment)
                    //.addToBackStack(null)
                    .commit();
            return true;
        }
        return false;
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        Fragment fragment = null;

        switch (item.getItemId()) {
            case R.id.navigation_home:
                fragment = frag1;

                break;
            case R.id.navigation_camera:
                fragment = frag2;

                break;
            case R.id.navigation_map:
                fragment = frag3;

                break;
        }
        return loadFragment(fragment);
    }
}

Я попытался несколькими способами попытаться сохранить исходный фрагмент, один из которых - onSavedInstanceState, как и другие предложения по переполнению стека.Однако во время выполнения я получаю сообщение об отсутствии ссылки на навигацию:

@Override
public void onSaveInstanceState(Bundle outState) {
   super.onSaveInstanceState(outState);
   outState.putInt("opened_fragment", navigation.getSelectedItemId());

}

как wнапример, использование следующего кода в методе OnCreate в операторе if (onSavedInstanceState == null):

navigation.setSelectedItemId(savedInstanceState.getInt("opened_fragment"));

В настоящее время приложение правильно переключается между тремя фрагментами и сохраняет необходимые данные,пока не произойдет изменение ориентации.Отображаемый фрагмент возвращается к frag1 и больше не может переключаться между фрагментами (я предполагаю, что это как-то связано с setOnNavigationItemSelectedListener ??).

Я новичок в разработке Android.

РЕДАКТИРОВАТЬ: Теперь с помощью ViewPager, который обрабатывает вышеуказанные проблемы

1 Ответ

0 голосов
/ 27 января 2019

Мне кажется, я нашел решение самостоятельно.Похоже, работает, и дают функциональность, мне нужно.Однако я хотел бы получить отзывы от любых экспертов относительно того, является ли это правильное решение.

Решение использует фрагмент тега, назначенный при использовании getSupportFragmentManager (). Replace, и проверяет, еслибыла загружена предыдущая версия фрагмента.Я не уверен, что моя логика в onNavigationItemSelected () великолепна, но я хотел бы получить любую обратную связь / критику

Обновлено FeedActivity.Java:

public class FeedActivity extends AppCompatActivity
    implements BottomNavigationView.OnNavigationItemSelectedListener {

private ReportFragment frag2;
private MapFragement frag3;
private HomeFragement frag1;

BottomNavigationView navigation;

private static final String TAG = "FeedActivity";

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

    navigation = findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(this);

    if(savedInstanceState==null) {
        frag1 = new HomeFragement();
        frag2 = new ReportFragment();
        frag3 = new MapFragement();
    }
    loadFragment(frag1, "home");

}

private boolean loadFragment(Fragment fragment, String tagID){
if(fragment != null){

            getSupportFragmentManager()
                    .beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                    .replace(R.id.fragment_container, fragment, tagID)
                    .addToBackStack(null)
                    .commit();

    return true;
}
return false;
}


@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    Fragment fragment = null;
    String tagID = null;
    switch(item.getItemId()){
        case R.id.navigation_home:
            Fragment cachedFragment1 = getSupportFragmentManager().findFragmentByTag("home");
            if (cachedFragment1 != null){
                fragment = cachedFragment1;
            }
            else{
            fragment = new HomeFragement();
            }
           tagID = "home";
            break;

        case R.id.navigation_camera:
            Fragment cachedFragment2 = getSupportFragmentManager().findFragmentByTag("cam");
            if (cachedFragment2 != null){
                fragment = cachedFragment2;
            }
            else{
                fragment = new ReportFragment();
            }
            tagID = "cam";
            break;

        case R.id.navigation_map:
            Fragment cachedFragment3 = getSupportFragmentManager().findFragmentByTag("map");
            if (cachedFragment3 != null){
                fragment = cachedFragment3;
            }
            else{
                fragment = new MapFragement();
            }
            tagID = "map";
            break;
    }
    return loadFragment(fragment, tagID);
}}
...