【问题标题】:Getting TabLayout view in fragment returns NullPointerException在片段中获取 TabLayout 视图返回 NullPointerException
【发布时间】:2021-01-30 22:55:56
【问题描述】:

我正在尝试将TabLayout 添加到片段中,我通过多个教程讨论了实现TabLayout 的主题,它们大致相同。我按照教程更改了一些方法以适应片段而不是通常的活动,但是在编译后它返回一个错误,从 xml 文件通过findViewById 获取Tablayout。尽管我已经检查过,但我还没有设法找到做错了什么。 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 类

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>

【问题讨论】:

    标签: java android android-fragments tabs fragment


    【解决方案1】:

    你不能在onCreateView()片段生命周期方法中使用getView()..因为片段视图尚未创建;实际上onCreateView() 创建了这个视图并将其返回。

    您只能在 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 下方。
    • @EdwardAarma 对不起,我没能找到你..你能不能给我一些照片
    • 抱歉解释不清楚,现在我在问题的末尾添加了一个截图。在那里你可以看到 TabLayout 位于屏幕中间,标签应该从它下面开始,但你可以看到左上角是标签的内容(单词“discovered”)。
    • 您需要通过将android:layout_below="@id/tabLayout" 添加到 ViewPager 来使 ViewPager 位于选项卡布局下方
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2016-05-31
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多