如何使用BottomNavigationView在两个方向更改时保留片段及其数据

时间:2019-01-27 08:02:25

标签: java android android-fragments bottomnavigationview

在完成了一些Youtube教程(例如https://www.youtube.com/watch?v=tPV8xA7m-iw)之后,我能够使用BottomNavigationView构建一个Activity,该Activity在三个不同的片段之间切换。

我不确定这是否是实现目标的最佳方法。我需要三个屏幕,其中一个屏幕(ReportFragment)将让用户输入我希望在用户在片段之间切换时保留的数据。

我遇到的困难还在于在方向改变时保留Fragment数据。

这是Fragment代码之一,我实现了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);
    }
}

我尝试了几种方法来尝试保留原始的Fragment,一种是onSavedInstanceState,另一种是关于Stack Overflow的建议。但是,在执行期间,我收到有关对导航的空引用的错误:

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

}

以及在if(onSavedInstanceState == null)语句的OnCreate方法中使用以下代码:

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

该应用程序当前可以在三个片段之间正确切换,并按需要保留数据,直到发生方向改变为止。显示的片段将还原为frag1,并且无法再在片段之间切换(我想这与setOnNavigationItemSelectedListener ??有关)。

我是Android开发的新手。

编辑:现在使用处理上述问题的ViewPager

1 个答案:

答案 0 :(得分:0)

我相信自己已经找到了 a 解决方案。它似乎可以正常工作,并提供我需要的功能。但是,我希望得到任何专家对它是否是 right 解决方案的反馈。

该解决方案使用在使用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);
}}