Android開發-Fragment嵌套Fragment

前言

在大多數公司中,他們會盡量少寫Activity,多使用Fragment,使項目變成一個千層餅,在本文章中我會給大家介紹一下Fragment嵌套Fragment的實現

使用依賴

    implementation 'com.google.android.material:material:1.2.0-alpha03'
    implementation "com.jakewharton:butterknife:10.0.0"
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'

遠程倉庫地址

buildscript {
    
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' } //遠程倉庫地址
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.1'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' } //遠程倉庫地址
    }
}

佈局實現

使用控件

  • BottomNavigationView依賴於material庫
com.google.android.material.bottomnavigation.BottomNavigationView
  • FrameLayout依賴於Android X庫
FrameLayout
  • TabLayout依賴於material庫
com.google.android.material.tabs.TabLayout
  • ViewPager依賴於Android X庫
androidx.viewpager.widget.ViewPager

xml代碼

  • activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#454545"
    >

    <FrameLayout
        android:id="@+id/main_page_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <!--底部按鈕-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/main_bottn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#292929"
        app:menu="@menu/butt_item"
        android:layout_alignParentBottom="true"
        />

</RelativeLayout>
  • butt_item,在res的menu中新建該文件,在BottomNavigationView的menu屬性中引用
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/discover"
        android:icon="@mipmap/icon_signal"
        android:title="discover"/>
    />
    <item
        android:id="@+id/product"
        android:icon="@mipmap/icon_index_line"
        android:title="product"/>
    />
    <item
        android:id="@+id/protein"
        android:icon="@mipmap/icon_link"
        android:title="protein"/>
    />
    <item
        android:id="@+id/store"
        android:icon="@mipmap/icon_homepage"
        android:title="store"/>
    />
    <item
        android:id="@+id/me"
        android:icon="@mipmap/icon_signal"
        android:title="me"/>
    />
</menu>

  • 父Fragment佈局(應當創建兩個進行區別)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

<com.google.android.material.tabs.TabLayout
    android:id="@+id/discover_tab"
    android:layout_width="match_parent"
    android:layout_height="60dp"/>

<androidx.viewpager.widget.ViewPager
    android:id="@+id/discover_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>


</LinearLayout>
  • 兩個子Fragment佈局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
     <!--這個第一個子Fragment設置爲A,第二個子Fragment設置爲B,進行區別-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="A/B"
        android:gravity="center"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

Java實現

第一步,創建父Fragment子Fragment對應的Java文件,當你繼承Fragment類,會要你創建三個方法onCreateonCreateViewonPause(),分別是創建這個Fragment,定義這個Fragment的視圖,結束這個Fragment,按照提示創建,重寫onCreateView,使用inflater獲得這個Fragment的佈局文件,並返回這個view,子Fragment和父Fragment的初始Java代碼如下:

public class Fragments extends Fragment {


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       //這個修改爲對應子Fragment和父Fragment的佈局文件
        View view = inflater.inflate(R.layout.father_fragment,null);
        return view;
    }
    
    @Override
    public void onPause() {
        super.onPause();
    }
}

第二步,首先在Mianactivity初始化控件和父Fragment對象(initFragment),這裏使用獲取id使用了ButterKnife,然後定義switchFragment方法,最後新建initView(), 在裏面使用bottomNavigationView控件對象**.setOnNavigationItemSelectedListener**方法中設置點擊事件的監聽和行爲 switchFragment,完成第一層的Fragment頁面切換

public class MainActivity extends AppCompatActivity {

    FragmentDiscover mManageFragment;
    FragmentProduct mDataFragment;
    FragmentManager mFm;
    @BindView(R.id.main_bottn)
    BottomNavigationView mbottomNavigationView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mbottomNavigationView = findViewById(R.id.main_bottn);
        initView();
        initFragment();

    }


    private void initView() {
        mbottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                if (item.getItemId() == R.id.discover) {
                    switchFragment(mManageFragment);
                } else if (item.getItemId() == R.id.product) {
                    switchFragment(mDataFragment);
                    mManageFragment.onResume();
                }
                return true;
            }
        });
    }

    private void initFragment() {
        mManageFragment = new FragmentDiscover();
        mDataFragment = new FragmentProduct();
        mFm = getSupportFragmentManager();
        switchFragment(mManageFragment);
    }

    private void switchFragment(Fragment targetFragment) {
        /*開啓事務*/
        FragmentTransaction fragmentTransaction = mFm.beginTransaction();
        /*頁面跳轉,參數類型:主FragmentID,需要跳轉的FragmentID*/
        fragmentTransaction.replace(R.id.main_page_container, targetFragment);
        /*提交事務*/
        fragmentTransaction.commit();
    }

}

最後一步,首先在MainFatherFragment獲取TabLayout和ViewPager的對象,然後設置公共適配器MyAdapter,應用mTitlemFragment中的數據,最後使用TabLayout的setupWithViewPager方法綁定ViewPager,使用第二層的聯動頁面切換

public class MainFatherFragment extends Fragment {
    TabLayout mTableLayout;
    private  ViewPager mViewPager;
    private MyAdapter adapter;
    private List<String> mTitle;
    private List<Fragment> mFragment;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       //綁定一下fragment資源文件以及生成fragment對象
        View view = inflater.inflate(R.layout.discover_fragment,null);
        mTableLayout=view.findViewById(R.id.discover_tab);
        mViewPager=view.findViewById(R.id.discover_pager);
        //標題欄數組
        mTitle = new ArrayList<>();
        mTitle.add("首頁");
        mTitle.add("中心");
        //fragment集合
        mFragment = new ArrayList<>();
        mFragment.add(new FragmentDiscoverSonA());
        mFragment.add(new FragmentDiscoverSonB());
       //在activity中使用 getSupportFragmentManager(),這裏是Fragment中使用如下方法
        adapter = new MyAdapter(getFragmentManager());
        mViewPager.setAdapter(adapter);
        //將TabLayout和ViewPager綁定在一起,一個動另一個也會跟着動
        mTableLayout.setupWithViewPager(mViewPager);
       //返回視圖
        return view;

    }
    //創建Fragment的適配器
    class MyAdapter extends FragmentPagerAdapter {

        public MyAdapter(FragmentManager fm) {
            super(fm);
        }
        //獲得每個頁面的下標
        @Override
        public Fragment getItem(int position) {
            return mFragment.get(position);
        }
        //獲得List的大小
        @Override
        public int getCount() {
            return mFragment.size();
        }
        //獲取title的下標
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitle.get(position);
        }
    }
    @Override
    public void onPause() {
        super.onPause();
    }

}

效果圖

在這裏插入圖片描述

項目地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章