使用 BottomNavigationView 在它们之间切换时保留片段状态

Posted

技术标签:

【中文标题】使用 BottomNavigationView 在它们之间切换时保留片段状态【英文标题】:Retaining fragments state in switching between them using BottomNavigationView 【发布时间】:2018-09-05 15:44:16 【问题描述】:

我有一个Bottom Navigation View,我想使用fragmentNavigation,这样每次用户点击navigation View 的部分时,fragment 应该加载以前的状态而不是创建新的fragment。我有一个Frame Layout,所有fragment 都应该加载或替换那个Frame Layout。 这是我的代码 opublic class MainActivity extends AppCompatActivity

    BottomNavigationView navigation;
    Home home;
    Trending trending;
    Upload upload;
    ImageView uploadImage;
    final public static int UPLOAD_ACTIVITY_CODE = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        navigation = findViewById(R.id.navigation);
        uploadImage = findViewById(R.id.uploadimg);
        home = new Home();
        trending = new Trending();
        upload = new Upload();
        fragmentLoad(home);
        uploadImage.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent intent = new Intent(getApplicationContext(), UploadActivity.class);
                startActivityForResult(intent,UPLOAD_ACTIVITY_CODE);
            
        );
        navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() 
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) 
                switch (item.getItemId())
                    case R.id.home:
                        fragmentLoad(home);
                        break;
                    case R.id.trending:
                        fragmentLoad(trending);
                        break;
                    case R.id.upload:
                        fragmentLoad(upload);
                        break;
                
                return true;
            
        );
    

    public void fragmentLoad(android.support.v4.app.Fragment fragment)
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.frame, fragment);
        transaction.commit();
    

    public void fragmentLoad(android.support.v4.app.Fragment fragment,Bundle bundle)
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction().show(fragment);
        fragment.setArguments(bundle);
        transaction.replace(R.id.frame, fragment);
        transaction.commit();
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==UPLOAD_ACTIVITY_CODE && resultCode==UPLOAD_ACTIVITY_CODE && data!=null)
            String desc = data.getStringExtra("Desc");
            String title= data.getStringExtra("Title");
            String photo= data.getStringExtra("PhotoUri");
            String duration= data.getStringExtra("duration");
            String video= data.getStringExtra("videoUri");
            Bundle bundle = new Bundle();
            bundle.putString("desc",desc);
            bundle.putString("title",title);
            bundle.putString("photo",photo);
            bundle.putString("duration",duration);
            bundle.putString("videoUri",video);
            fragmentLoad(upload,bundle);
            navigation.setSelectedItemId(R.id.upload);
        
    

【问题讨论】:

【参考方案1】:

您应该从每个片段创建一个实例,然后使用FragmentManager 根据底部导航状态显示它们。您应该在Upload 片段类中编写一个名为setData 的方法来重新初始化其视图。我为这个案例写了一个类,希望对你有所帮助。

public class MainActivity extends AppCompatActivity  

    public static final int UPLOAD_ACTIVITY_CODE = 100;
    private BottomNavigationView navigation;
    private ImageView uploadImage;
    private Home home;
    private Trending trending;
    private Upload upload;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        navigation = findViewById(R.id.navigation);
        uploadImage = findViewById(R.id.uploadimg);
        home = new Home();
        trending = new Trending();
        upload = new Upload();

        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
        navigation.getMenu().findItem(R.id.home).setChecked(true);

        getSupportFragmentManager().beginTransaction()
                .add(R.id.frame, home)
                .add(R.id.frame, category)
                .add(R.id.frame, search)
                .commit();
        setTabStateFragment(TabState.HOME);

        uploadImage.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent intent = new Intent(getApplicationContext(), UploadActivity.class);
                startActivityForResult(intent, UPLOAD_ACTIVITY_CODE);
            
        );
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == UPLOAD_ACTIVITY_CODE && resultCode == UPLOAD_ACTIVITY_CODE && data != null) 
            String desc = data.getStringExtra("Desc");
            String title = data.getStringExtra("Title");
            String photo = data.getStringExtra("PhotoUri");
            String duration = data.getStringExtra("duration");
            String video = data.getStringExtra("videoUri");
            Bundle bundle = new Bundle();
            bundle.putString("desc", desc);
            bundle.putString("title", title);
            bundle.putString("photo", photo);
            bundle.putString("duration", duration);
            bundle.putString("videoUri", video);
            upload.setData(bundle);
            setTabStateFragment(TabState.UPLOAD);
        
    

    private void setTabStateFragment(TabState state) 
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        switch (state) 
            case HOME: 
                transaction.show(home);
                transaction.hide(trending);
                transaction.hide(upload);
            
            case TRENDING: 
                transaction.hide(home);
                transaction.show(trending);
                transaction.hide(upload);
            
            case UPLOAD: 
                transaction.hide(home);
                transaction.hide(trending);
                transaction.show(upload);
            
        
        transaction.commit();
    

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() 

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) 
            switch (item.getItemId()) 
                case R.id.home: 
                    setTabStateFragment(TabState.HOME);
                    return true;
                
                case R.id.trending: 
                    setTabStateFragment(TabState.TRENDING);
                    return true;
                
                case R.id.upload: 
                    setTabStateFragment(TabState.UPLOAD);
                    return true;
                
            
            return false;
        
    ;

    enum TabState 
        HOME,
        TRENDING,
        UPLOAD,
    


【讨论】:

我已经添加了我想要自定义的代码。我无法弄清楚我的代码。你能帮帮我吗 @PrathamKhurana:我为你重写了解决方案;)

以上是关于使用 BottomNavigationView 在它们之间切换时保留片段状态的主要内容,如果未能解决你的问题,请参考以下文章

使用androidx的BottomNavigationView

如何使用adjustResize设置隐藏键盘下方的BottomNavigationView

BottomNavigationView结合ViewPager

如何在Android的BottomNavigationView中设置填充项

Android BottomNavigationView 每次使用导航组件重新创建片段

如何在没有 ActionBar 的 AndroidX 中设置 BottomNavigationView