简体   繁体   English

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

[英]How to change fragment with the Bottom Navigation Activity?

I created a new project with the "Bottom Navigation Activity":我用“底部导航活动”创建了一个新项目:

在此处输入图片说明

This is the generated code:这是生成的代码:

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);
    }

}

How can I change to new Fragments with the Bottom Bar?如何使用底部栏更改为新片段? For example I have 3 Fragments: Fragment1 Fragment2 and Fragment3 And I want to change to them with the 3 buttons from the Bottom Bar.例如,我有 3 个 Fragment:Fragment1 Fragment2 和 Fragment3 我想用底部栏中的 3 个按钮更改它们。 Also I want that I can switch the Fragments by swiping my finger left and right how can I do that?另外我希望我可以通过左右滑动手指来切换片段,我该怎么做?

The way I would do it is, I would first add three methods similar to this one (each for a single fragment. Replace the layout name and the fragment object to the appropriate fragment that is being switched to):我的做法是,我首先添加三个与此类似的方法(每个用于一个片段。将布局名称和片段对象替换为要切换到的适当片段):

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

So your switch statement would end up looking like this:所以你的 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;
        }

As for switching the fragments by swiping to the sides, I believe you would need a ViewPager .至于通过向两侧滑动来切换片段,我相信您需要一个ViewPager

It's pretty "simple".这非常“简单”。

  1. Create your Fragments.创建您的片段。 Let's say we want 3 fragments;假设我们想要 3 个片段; FragmentA , FragmentB and FragmentC with FragmentA being the first Fragment we want on the BottomNavigationView. FragmentAFragmentBFragmentC其中FragmentA是我们想要在 BottomNavigationView 上的第一个 Fragment。
  2. In your Activity, go to the onNavigationItemSelected method and change the content to this:在您的 Activity 中,转到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. In your onCreate() method, do this:在您的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); }

If you do not add FragmentA in the onCreate() , the activity is blank when you first launch it.如果您没有在onCreate()添加FragmentA ,那么当您第一次启动它时该活动是空白的。

If you are wondering what R.id.content refers to, it is the Id of the Framelayout in your activity's layout.如果您想知道R.id.content指的是什么,它是您活动布局中 Framelayout 的 Id。 It initially contains a TextView , delete the TextView so it looks like this:它最初包含一个TextView ,删除 TextView 使其看起来像这样:

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

Finally, ft and currentFragment are defined like this:最后, ftcurrentFragment定义如下:

Fragment currentFragment = null;
FragmentTransaction ft;

Not sure about elegance, but this works.不确定优雅,但这是有效的。

The best way is to use a ViewPager with a FragmentPagerAdapter .最好的方法是使用带有FragmentPagerAdapterViewPager Since it cashes the fragments inside it.因为它兑现了里面的碎片。 Use setOnNavigationItemSelectedListener with the BottomNavigationView to listen for the user's clicks.使用setOnNavigationItemSelectedListenerBottomNavigationView来监听用户的点击。 And use viewPager.setCurrentItem(..) to move between pages.并使用viewPager.setCurrentItem(..)在页面之间移动。

Creating a new fragment everytime the user clicks on an item in the bottom navigation view isn't a good solution (especially when the user clicks on the item of the screen that he is currently at, the solution above will create a new fragment even for this case)每次用户点击底部导航视图中的项目时创建一个新片段并不是一个好的解决方案(特别是当用户点击他当前所在屏幕的项目时,上面的解决方案将创建一个新片段,即使是这个案例)

//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);
        }

    }

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

 bottom_navigation_view?.setupWithNavController(navController)

You can switch fragments through below code if you are using Jetpack Navigation.如果您使用 Jetpack Navigation,您可以通过以下代码切换片段。

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

For more information go through this doc : https://codelabs.developers.google.com/codelabs/android-navigation/#0有关更多信息,请参阅此文档: https : //codelabs.developers.google.com/codelabs/android-navigation/#0

There is another way to avoid recreating fragment -- fm.beginTransaction().hide(active).show(aimFragment)还有另一种避免重新创建片段的方法fm.beginTransaction().hide(active).show(aimFragment)

My example is follow(just copy from my project recent):我的例子如下(只是从我最近的项目中复制):

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;
        };
}

It seems efficient and will work well until you rotate your phone.它看起来很有效,并且在您旋转手机之前都能很好地工作。 And I fixed it by adding the code following in the manifest file to the activity to retain the fragment state.我通过将清单文件中的以下代码添加到活动以保留片段状态来修复它。 (eg at AndroidManifest.xml ): (例如在AndroidManifest.xml ):

android:configChanges="screenSize|orientation|screenLayout"

you can use this one你可以用这个

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将底部导航活动转换为片段 - Convert Bottom Navigation Activity to Fragment 如何从活动返回导航底部的特定片段? - How to return from activity to a specific fragment in navigation bottom? 如何从活动返回到导航底部的特定片段 - How to return from activity to a specific fragment in navigation bottom 如何实现底部导航栏事务不是碎片,而是活动 class? - How to Implementing bottom navigation bar transaction not to fragment , however to Activity class? 通过底部导航视图通过活动将价值从一个片段传递到另一个片段 - Pass value from fragment to fragment through activity with bottom navigation view 如何将活动更改为片段 - How TO Change Activity To Fragment Kotlin:使用 Kotlin 提供的标准底部导航活动时如何将数据从 MainActivity 传递到片段 - Kotlin: How to pass data from the MainActivity to a fragment when working with the standard bottom navigation activity provided by Kotlin 我想在底部导航活动的片段中添加秒表,但 findviewbyid 显示错误。 如何解决? - I wanted to add Stopwatch in a fragment with bottom navigation activity but findviewbyid shows error. How to resolve? 使用 Fragment 和 FragmentActivity 更改导航抽屉中的活动 - Change activity in a navigation Drawer with Fragment and FragmentActivity 底部导航栏和 NestedScroll View 隐藏了我的片段活动 - Bottom Navigation Bar and NestedScroll View hide my fragment activity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM