簡體   English   中英

如何使用底部導航活動更改片段?

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

我用“底部導航活動”創建了一個新項目:

在此處輸入圖片說明

這是生成的代碼:

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 個 Fragment:Fragment1 Fragment2 和 Fragment3 我想用底部欄中的 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

這非常“簡單”。

  1. 創建您的片段。 假設我們想要 3 個片段; FragmentAFragmentBFragmentC其中FragmentA是我們想要在 BottomNavigationView 上的第一個 Fragment。
  2. 在您的 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. 在您的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); }

如果您沒有在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;

不確定優雅,但這是有效的。

最好的方法是使用帶有FragmentPagerAdapterViewPager 因為它兌現了里面的碎片。 使用setOnNavigationItemSelectedListenerBottomNavigationView來監聽用戶的點擊。 並使用viewPager.setCurrentItem(..)在頁面之間移動。

每次用戶點擊底部導航視圖中的項目時創建一個新片段並不是一個好的解決方案(特別是當用戶點擊他當前所在屏幕的項目時,上面的解決方案將創建一個新片段,即使是這個案例)

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

如果您使用 Jetpack Navigation,您可以通過以下代碼切換片段。

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

還有另一種避免重新創建片段的方法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 ):

android:configChanges="screenSize|orientation|screenLayout"

你可以用這個

                    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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM