前言
在大多數公司中,他們會盡量少寫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類,會要你創建三個方法onCreate、onCreateView和onPause(),分別是創建這個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,應用mTitle和 mFragment中的數據,最後使用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();
}
}