如何使用底部导航活动更改片段?

时间:2017-03-29 21:29:42

标签: java android android-fragments android-activity

我使用“底部导航活动”创建了一个新项目:

enter image description here

这是生成的代码:

package com.aaron.waller.mrpolitik;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView mTextMessage;

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

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
            }
            return true;
        }

    };

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

        mTextMessage = (TextView) findViewById(R.id.message);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

}

如何使用底栏更改为新片段? 例如,我有3个碎片: 片段1 Fragment2和 Fragment3 我想用Bottom Bar中的3个按钮更改它们。 另外我想要我可以左右滑动手指来切换碎片我该怎么做?

8 个答案:

答案 0 :(得分:20)

我会这样做,我首先会添加三个与此类似的方法(每个方法用于单个片段。将布局名称和片段对象替换为正在切换到的相应片段):

public void switchToFragment1() {
    FragmentManager manager = getSupportFragmentManager();
    manager.beginTransaction().replace(R.id.your_fragment_layout_name, new Fragment1()).commit();
}

所以你的switch语句最终看起来像这样:

        switch (item.getItemId()) {
            case R.id.navigation_home:
                mTextMessage.setText(R.string.title_home);
                switchToFragment1();
                break;

            case R.id.navigation_dashboard:
                mTextMessage.setText(R.string.title_dashboard);                    
                switchToFragment2();
                break;

            case R.id.navigation_notifications:
                mTextMessage.setText(R.string.title_notifications);                     
                switchToFragment3();
                break;
        }

至于通过向侧面滑动切换片段,我相信你需要一个ViewPager

答案 1 :(得分:10)

很漂亮"简单"。

  1. 创建碎片。我们说我们想要3个片段; FragmentAFragmentBFragmentC FragmentA是BottomNavigationView上我们想要的第一个片段。
  2. 在您的活动中,转到onNavigationItemSelected方法并将内容更改为:

     private BottomNavigationView.OnNavigationItemSelectedListener  
       mOnNavigationItemSelectedListener
           = new BottomNavigationView.OnNavigationItemSelectedListener(){
    
       @Override
       public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    
        switch (item.getItemId()) {
            case R.id.frag_a:
                currentFragment = new FragmentA();
                ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.content, currentFragment);
                ft.commit();
                return true;
            case R.id.frag_b:
                currentFragment = new FragmentB();
                ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.content, currentFragment);
                ft.commit();
                return true;
            case R.id.frag_c:
                currentFragment = new FragmentC();
                ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.content, currentFragment);
                ft.commit();
                return true;
        }
    
        return false;
     }
    
    };
    
  3. onCreate()方法中,请执行以下操作:

      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client_profile);
        ft = getSupportFragmentManager().beginTransaction();
        currentFragment = new FragmentA();
        ft.replace(R.id.content, currentFragment);
        ft.commit();
    
        BottomNavigationView navigation = (BottomNavigationView)  
        findViewById(R.id.navigation); navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
      }
    
  4. 如果您未在FragmentA中添加onCreate(),则首次启动该活动时该活动为空。

    如果您想知道R.id.content引用了什么,那么它就是您的活动布局中的Framelayout的ID。它最初包含TextView,删除TextView所以它看起来像这样:

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    

    最后,ftcurrentFragment的定义如下:

    Fragment currentFragment = null;
    FragmentTransaction ft;
    

    不确定优雅,但这很有效。

答案 2 :(得分:7)

最好的方法是使用ViewPagerFragmentPagerAdapter。因为它会在里面兑现碎片。使用setOnNavigationItemSelectedListenerBottomNavigationView一起收听用户的点击次数。并使用viewPager.setCurrentItem(..)在页面之间移动。

每次用户点击底部导航视图中的项目时创建一个新片段都不是一个好的解决方案(特别是当用户点击他当前所在的屏幕项目时,上面的解决方案将创建一个新的甚至为这种情况分段)

答案 3 :(得分:2)

//fully tested  
  public class DashBoardActivity extends AppCompatActivity {

        Fragment fragment = null;
        FragmentTransaction fragmentTransaction;

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

            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.navigation_home:
                        return true;
                    case R.id.navigation_dashboard:
                        fragment = new FragmentDashBoard();
                        switchFragment(fragment);
                        return true;
                    case R.id.navigation_notifications:
                        fragment = new FragmentNotification();
                        switchFragment(fragment);
                        return true;
                }
                return false;
            }
        };


        private void switchFragment(Fragment fragment) {
            fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.content, fragment);
            fragmentTransaction.commit();
        }

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

            BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
            navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
            navigation.setSelectedItemId(R.id.navigation_dashboard);
        }

    }

答案 4 :(得分:0)

还有另一种避免重新创建片段的方法-fm.beginTransaction().hide(active).show(aimFragment)

我的示例如下(仅从最近的项目中复制):

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.main_bottom_navigation) BottomNavigationView mBottomNavigationView;
    final Fragment mTaskListFragment = new TaskListFragment();
    final Fragment mUserGroupFragment = new UserGroupFragment();
    final Fragment mUserMeFragment = new UserMeFragment();
    final FragmentManager fm = getSupportFragmentManager();
    Fragment active = mTaskListFragment;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mBottomNavigationView
                .setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
        fm.beginTransaction().add(R.id.main_fragment_container, mUserMeFragment, "3")
                .hide(mUserMeFragment).commit();
        fm.beginTransaction().add(R.id.main_fragment_container, mUserGroupFragment, "2")
                .hide(mUserGroupFragment).commit();
        fm.beginTransaction().add(R.id.main_fragment_container, mTaskListFragment, "1").commit();

    }


    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = item -> {
//        TODO: 这种切换方式比较快,但横竖屏切换会出问题,已经
            switch (item.getItemId()) {
                case R.id.nav_list:
                    fm.beginTransaction().hide(active).show(mTaskListFragment).commit();
                    active = mTaskListFragment;
                    break;
                case R.id.nav_group:
                    fm.beginTransaction().hide(active).show(mUserGroupFragment).commit();
                    active = mUserGroupFragment;
                    break;
                case R.id.nav_me:
                    fm.beginTransaction().hide(active).show(mUserMeFragment).commit();
                    active = mUserMeFragment;
                    break;
            }
            return true;
        };
}

这似乎很有效,并且可以很好地工作,直到您旋转手机。我通过禁止在此活动中旋转(在AndroidManifest.xml)来解决了这个问题:

        <activity android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:launchMode="singleTop">

也许保存active可以更好地解决它,但是我没有尝试过。 (对不起,我英语不好)

答案 5 :(得分:0)

简单的方法是使用导航组件:

 bottom_navigation_view?.setupWithNavController(navController)

答案 6 :(得分:0)

如果使用Jetpack导航,则可以通过以下代码切换片段。

val navController = findNavController(R.id.your_nav_host_fragment)
navController.navigate(R.id.your_fragment_id_in_menu)

有关更多信息,请阅读此文档:https://codelabs.developers.google.com/codelabs/android-navigation/#0

答案 7 :(得分:-1)

你可以使用这个

                    fragmentManager = getFragmentManager();
                    transaction = fragmentManager.beginTransaction();

                    FragmentA a = new FragmentA();
                    transaction.replace(R.id.frame, a);
                    transaction.commit();