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

}

效果图

在这里插入图片描述

项目地址

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