在片段 returns 中获取 TabLayout 视图 NullPointerException
Getting TabLayout view in fragment returns NullPointerException
我正在尝试将 TabLayout
添加到片段中,我通过多个教程讨论了实现 TabLayout
的主题,它们大致相同。我按照教程更改了一些方法以适应片段而不是通常的 activity 但是在编译它之后 returns 从 xml 文件中获取 Tablayout
时出错findViewById
。尽管我检查了很多,但我还没有设法找到做错了什么。 TabLayout
在片段中,因为我使用 BottomNavigation
作为应用程序的主导航,但我想使用 TabLayout
来显示片段内的额外信息。
这是包含 TabLayout 的 Fragment
public class LocationsFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
//The next line has the NullPointerException.
TabLayout tabLayout = getView().findViewById(R.id.tabLayout);
TabItem discoveredTab = getView().findViewById(R.id.discoveredTab);
TabItem allLocationsTab = getView().findViewById(R.id.allTab);
ViewPager viewPager = getView().findViewById(R.id.viewPager);
PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
} else if (tab.getPosition() == 1){
pagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
View root = inflater.inflate(R.layout.fragment_locations, container, false);
return root;
}
这是 PagerAdapter class
public class PagerAdapter extends FragmentPagerAdapter {
private int numOfTabs;
public PagerAdapter(FragmentManager fragmentManager, int numOfTabs){
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.numOfTabs = numOfTabs;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new TabDiscoveredFragment();
case 1:
return new TabAllFragment();
default:
return null;
}
}
@Override
public int getCount() {
return numOfTabs;
}
}
这是布局文件
<?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"
tools:context=".ui.journey.JourneyFragment">
<RelativeLayout
android:id="@+id/statLayout"
android:layout_width="match_parent"
android:layout_height="65sp"
android:layout_marginStart="20sp"
android:layout_marginEnd="20sp"
android:layout_marginTop="30sp"
android:background="@drawable/layout_bg_round_all">
//TextViews which are irrelevant to the example
</RelativeLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/statLayout"
android:layout_marginTop="20sp">
<com.google.android.material.tabs.TabItem
android:id="@+id/discoveredTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Discovered" />
<com.google.android.material.tabs.TabItem
android:id="@+id/allTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="All locations" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/viewPager">
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>
您不能在 onCreateView()
片段生命周期方法中使用 getView()
.. 因为片段视图尚未创建;实际上 onCreateView()
创建此视图并 returns 返回。
您只能在 onCreateView()
之后的片段生命周期方法中使用 getView()
要解决此问题,您需要使用膨胀视图本身,将其应用到您的代码中,将 getView()
替换为 root
... 但在方法的最开头声明它。
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_locations, container, false);
//The next line has the NullPointerException.
TabLayout tabLayout = root.findViewById(R.id.tabLayout);
TabItem discoveredTab = root.findViewById(R.id.discoveredTab);
TabItem allLocationsTab = root.findViewById(R.id.allTab);
ViewPager viewPager = root.findViewById(R.id.viewPager);
PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
} else if (tab.getPosition() == 1){
pagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
return root;
}
我正在尝试将 TabLayout
添加到片段中,我通过多个教程讨论了实现 TabLayout
的主题,它们大致相同。我按照教程更改了一些方法以适应片段而不是通常的 activity 但是在编译它之后 returns 从 xml 文件中获取 Tablayout
时出错findViewById
。尽管我检查了很多,但我还没有设法找到做错了什么。 TabLayout
在片段中,因为我使用 BottomNavigation
作为应用程序的主导航,但我想使用 TabLayout
来显示片段内的额外信息。
这是包含 TabLayout 的 Fragment
public class LocationsFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
//The next line has the NullPointerException.
TabLayout tabLayout = getView().findViewById(R.id.tabLayout);
TabItem discoveredTab = getView().findViewById(R.id.discoveredTab);
TabItem allLocationsTab = getView().findViewById(R.id.allTab);
ViewPager viewPager = getView().findViewById(R.id.viewPager);
PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
} else if (tab.getPosition() == 1){
pagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
View root = inflater.inflate(R.layout.fragment_locations, container, false);
return root;
}
这是 PagerAdapter class
public class PagerAdapter extends FragmentPagerAdapter {
private int numOfTabs;
public PagerAdapter(FragmentManager fragmentManager, int numOfTabs){
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.numOfTabs = numOfTabs;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new TabDiscoveredFragment();
case 1:
return new TabAllFragment();
default:
return null;
}
}
@Override
public int getCount() {
return numOfTabs;
}
}
这是布局文件
<?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"
tools:context=".ui.journey.JourneyFragment">
<RelativeLayout
android:id="@+id/statLayout"
android:layout_width="match_parent"
android:layout_height="65sp"
android:layout_marginStart="20sp"
android:layout_marginEnd="20sp"
android:layout_marginTop="30sp"
android:background="@drawable/layout_bg_round_all">
//TextViews which are irrelevant to the example
</RelativeLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/statLayout"
android:layout_marginTop="20sp">
<com.google.android.material.tabs.TabItem
android:id="@+id/discoveredTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Discovered" />
<com.google.android.material.tabs.TabItem
android:id="@+id/allTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="All locations" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/viewPager">
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>
您不能在 onCreateView()
片段生命周期方法中使用 getView()
.. 因为片段视图尚未创建;实际上 onCreateView()
创建此视图并 returns 返回。
您只能在 onCreateView()
getView()
要解决此问题,您需要使用膨胀视图本身,将其应用到您的代码中,将 getView()
替换为 root
... 但在方法的最开头声明它。
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_locations, container, false);
//The next line has the NullPointerException.
TabLayout tabLayout = root.findViewById(R.id.tabLayout);
TabItem discoveredTab = root.findViewById(R.id.discoveredTab);
TabItem allLocationsTab = root.findViewById(R.id.allTab);
ViewPager viewPager = root.findViewById(R.id.viewPager);
PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
} else if (tab.getPosition() == 1){
pagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
return root;
}