web-dev-qa-db-ja.com

ボトムナビゲーションアクティビティでフラグメントを変更する方法は?

「下部ナビゲーションアクティビティ」を使用して新しいプロジェクトを作成しました。

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つのフラグメントがあります:Fragment1 Fragment2とFragment3そして、ボトムバーの3つのボタンでそれらに変更したいと思います。また、指を左右にスワイプしてフラグメントを切り替えることができるようにするにはどうすればよいですか?

15
TheUseracc awd

私がそれをする方法は、最初にこれに似た3つのメソッドを追加します(それぞれ単一のフラグメント用です。レイアウト名とフラグメントオブジェクトを、切り替えられる適切なフラグメントに置き換えます):

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 が必要になると思います。

20
Abdel Rahman

とても「シンプル」です。

  1. フラグメントを作成します。 3つのフラグメントが必要だとしましょう。 FragmentAFragmentB、およびFragmentCで、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() methodで、次を実行します。

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

onCreate()FragmentAを追加しない場合、アクティビティは最初の起動時に空白になります。

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

優雅さについてはわかりませんが、これは機能します。

10

最善の方法は、ViewPagerFragmentPagerAdapterとともに使用することです。内部のフラグメントをキャッシュするため。 setOnNavigationItemSelectedListenerとともにBottomNavigationViewを使用して、ユーザーのクリックをリッスンします。また、viewPager.setCurrentItem(..)を使用してページ間を移動します。

ユーザーが下部ナビゲーションビューでアイテムをクリックするたびに新しいフラグメントを作成するのは良い解決策ではありません(特に、ユーザーが現在いる画面のアイテムをクリックすると、上記のソリューションは新しいフラグメントを作成しますこの場合)

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

    }
2
Vivek Shah

フラグメントの再作成を回避する別の方法があります-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">

多分save activeはそれをより良く修正できますが、私は試していません。 (英語が下手ですごめんなさい)

0
jianQ huang

簡単な方法は、ナビゲーションコンポーネントを使用することです。

 bottom_navigation_view?.setupWithNavController(navController)
0
timothyjc