Android开发:利用Android Studio自带的底部导航栏和ViewPager+TabLayout创建顶部导航栏

目录

效果图

底部导航栏

顶部导航栏

底部导航栏首个Fragment代码

适配器代码

顶部导航栏首个Fragment代码

 顶部导航栏另外三个Fragment代码

 ​顶部导航栏四个Fragment的XML


效果图

学Android开发开始实操,第一步肯定要把大致布局搞定。做这个布局用到的知识难点有fragment,生命周期。

底部导航栏

首先使用Android Studio创建自带的组件创建底部导航栏(Bottom Navigation Views Activity)。创建出来的四个页面就是四个Fragment。这里为了代码简洁,不使用官方创建的MeViewModel.java,就把相关的代码注释了。

public class MeFragment extends Fragment {

    private FragmentMeBinding binding;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        //MeViewModel meViewModel =new ViewModelProvider(this).get(MeViewModel.class);

        binding = FragmentMeBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        //final TextView textView = binding.textMe;
        //meViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
        return root;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

顶部导航栏

那么接下来就需要在其中一个Fragment创建顶部导航栏,这里选择的是第一个fragment——HomeFragment(首页)。可以看出在底部导航栏中官方使用的是Binding,但实际上比较常用的还是View,所以我就把首页的binding改成View,以及下面创建顶部导航栏的四个fragment也都有View。说白了就是把顶部导航栏的四个fragment嵌套到底部导航栏的一个fragment中。

底部导航栏首个Fragment代码

主要作用就是将顶部导航栏的四个title和fragment加入到homefragment。

重点讲一下这里出现的一个bug,花了我半天才解决。

现象:如果不加上pager.setOffscreenPageLimit(3),会出现切换底部导航再切换回首页时,首页中该显示的文字没有显示出来。

必备知识:先了解下父子fragment。顶部四个fragment是底部HomeFragment的ChildFragment,也就是HomeFragment是顶部四个fragment的ParentFragment。父fragment的消失会导致子fragment的消失。

原因:底部导航的切换,会导致切换前的fragment被杀掉,也就是HomeFragment被杀掉,再切回来时,子fragment并没有被创建,所以该显示的文字没有显示出来。

解决办法:那么我选择的解决办法是不让fragment被杀掉。所以pager.setOffscreenPageLimit(3)的意思就是让3个fragment“活”在内存里。

public class HomeFragment extends Fragment {

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        pager = view.findViewById(R.id.page);
        tabLayout = view.findViewById(R.id.tab_layout);
        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    private ViewPager pager;
    private FragmentAdapter fragmentAdapter;
    private List<TabFragment> fragmentList;
    private TabLayout tabLayout;
    private List<String> mTitles;
    private String[] title = {"关注", "推荐", "排行榜", "会员"};


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        fragmentList=new ArrayList<>();
        mTitles=new ArrayList<>();
        for(int i=0;i<title.length;i++){
            mTitles.add(title[i]);
        }
        fragmentList.add(new AttentionFragment(title[0]));
        fragmentList.add(new TabFragment(title[1]));
        fragmentList.add(new ListFragment(title[2]));
        fragmentList.add(new VipFragment(title[3]));

        fragmentAdapter = new FragmentAdapter(getChildFragmentManager(), fragmentList, mTitles);
        pager.setAdapter(fragmentAdapter);
        //Set the number of offscreen pages (childfragments to keep in memory)
        pager.setOffscreenPageLimit(3);

        tabLayout.setupWithViewPager(pager);

        // 第二个选项卡的索引,注意索引从 0 开始
        int tabIndexToSwitchTo = 1;
        //转至第二个选项卡
        pager.setCurrentItem(tabIndexToSwitchTo);

    }
}

适配器代码

public class FragmentAdapter extends FragmentPagerAdapter {

    //各导航的Fragment
    private List<TabFragment> mFragmentList;
    //导航的标题
    private List<String> mTitle;

    public FragmentAdapter(FragmentManager fragmentManager, List<TabFragment>fragments, List<String>title){
        super(fragmentManager);
        mFragmentList=fragments;
        mTitle=title;

    }
    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitle.get(position);
    }
}

顶部导航栏首个Fragment代码

public class TabFragment extends Fragment {
    private TextView titleTv;

    private String mTitle;

    //这个构造方法是便于各导航同时调用一个fragment
    public TabFragment(String title){
        mTitle=title;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.fragment_tab,container,false);
        titleTv=view.findViewById(R.id.tv_title);
        titleTv.setText(mTitle);
        return view;
    }
}

 顶部导航栏另外三个Fragment代码

这三个代码都是继承首个fragment代码

public class ListFragment extends TabFragment{
    private TextView titleTv;

    public ListFragment(String title){
        super(title);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.fragment_list,container,false);
        titleTv=view.findViewById(R.id.list_title);
        titleTv.setText("排行榜");
        return view;

    }

  @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Lifecycle1:","onCreate");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("Lifecycle1:","onDestroyView");
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Log.d("Lifecycle1:","onStart");
    }
    @Override
    public void onResume() {
        super.onResume();
        Log.d("Lifecycle1:","onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("Lifecycle1:","onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("Lifecycle1:","onStop");
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("Lifecycle1:","onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("Lifecycle1:","onDetach");
    }

}

 

顶部导航栏四个Fragment的XML

<?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">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="20sp"
        android:gravity="center"/>

</LinearLayout>

猜你喜欢

转载自blog.csdn.net/Night_Journey/article/details/132814065