目录
效果图
底部导航栏
顶部导航栏
底部导航栏首个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中。
主要作用就是将顶部导航栏的四个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 fragmentList;
private TabLayout tabLayout;
private List 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
public class FragmentAdapter extends FragmentPagerAdapter {
//各导航的Fragment
private List mFragmentList;
//导航的标题
private List mTitle;
public FragmentAdapter(FragmentManager fragmentManager, Listfragments, Listtitle){
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);
}
}
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代码
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");
}
}