简体   繁体   English

片段中的 getArguments().getString() 返回 null

[英]getArguments().getString() in fragment returns null

In the app I'm working on I'm retrieving some data from a database.在我正在处理的应用程序中,我正在从数据库中检索一些数据。 I have a tablayout with fragments on my activity and I need to push data to a specific tab.我的活动中有一个带有片段的 tablayout,我需要将数据推送到特定的选项卡。 Because of the tabs I'm working with an ViewPagerAdapter;由于我正在使用ViewPagerAdapter;的选项卡ViewPagerAdapter; so the data goes from the MainActivity to the ViewPagerAdapter , to the fragment within a bundle.所以数据从MainActivityViewPagerAdapter ,再到包中的片段。 I think it's because that extra stop that I'm not getting the bundle to the fragment itself but I might be wrong.我认为这是因为额外的停止,我没有把包放到片段本身,但我可能是错的。

The issue is when creating DescriptionTab.java and using getArguments().getString("Description") , getString()` is null, thus no data was revieved.问题是在创建DescriptionTab.java并使用getArguments().getString("Description") ,getString()` 为空,因此没有数据被审查。

MainActivity.java主活动.java

public class MainActivity extends AppCompatActivity {

    public String description;
    private TabLayout tabLayout;
    private ViewPager viewpager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        description = "some text";
        tabLayout = findViewById(R.id.takenTabs);
        viewpager = findViewById(R.id.viewpager);

        setupViewPager(viewpager);

        tabLayout.setupWithViewPager(viewpager);
    }

    private void setupViewPager(ViewPager viewpager) {
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

        Bundle bundle = new Bundle();
        bundle.putString("Description", description);
        Fragment fragmentDesc = new DescriptionTab();
        fragmentDesc.setArguments(bundle);

        viewPagerAdapter.addFragment(fragmentDesc, "Beschrijving"); // this line can crash
        viewPagerAdapter.addFragment(new UsersTab(), "Ingeschreven"); // this line can crash
        viewPagerAdapter.addFragment(new CommentsTab(), "Opmerkingen"); // this line can crash
        viewpager.setAdapter(viewPagerAdapter);
    }
}

I get the discription string from the database but to make it simpler right now I'm just creating it in the MainActivity.我从数据库中获取描述字符串,但现在为了使它更简单,我只是在 MainActivity 中创建它。 I do know for sure it actually retrieves data from the database, because it shows the data when I push it to a TextView .我确实知道它实际上是从数据库中检索数据,因为当我将数据推送到TextView时它会显示数据。 There's 3 tabs, but for now I'm only trying to pass data to the Description tab.有 3 个选项卡,但现在我只想将数据传递到描述选项卡。

ViewPagerAdapter.java ViewPagerAdapter.java

public class ViewPagerAdapter extends FragmentPagerAdapter {

    private final ArrayList<Fragment> fragmentsList = new ArrayList<>(); // this line can crash
    private final ArrayList<String> fragmentTitle = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm); }

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

    @Override
    public int getCount() {
        return fragmentsList.size();
    }

    public void addFragment(Fragment fragment, String tabTitle) {
        fragmentsList.add(fragment); // this line can crash
        fragmentTitle.add(tabTitle);
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentTitle.get(position);
    }
}

I've tried creating the fragment and the bundle with the data in the addFragment() method before adding it to fragmentsList but that didn't work either.在将它添加到 fragmentList 之前,我已经尝试在 addFragment() 方法中使用数据创建片段和包,但这也不起作用。

DescriptionTab.java说明Tab.java

public class DescriptionTab extends Fragment {
    
    public DescriptionTab() {
        // Required empty public constructor
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle state) {

        View rootView = inflater.inflate(R.layout.description_tab, container, false);

        final Bundle args = getArguments();
        final String description = args.getString("Description");

        TextView descriptionText = rootView.findViewById(R.id.descriptionTxt);
        descriptionText.setText(description);

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.description_tab, container, false);
    }
}

getString("Description") is supposed to retrieve the data, but Android Studio already inspects it and tells me it may produce NullPointerException. getString("Description") 应该检索数据,但 Android Studio 已经检查它并告诉我它可能会产生 NullPointerException。 I'm guessing it WILL produce NullPointerException because I can't find the issue in other parts of the code myself.我猜它会产生 NullPointerException,因为我自己在代码的其他部分找不到问题。

Please tell me, If you know what I'm doing wrong or why it's not working.请告诉我,如果您知道我做错了什么或为什么它不起作用。

viewPagerAdapter.addFragment() is an anti-pattern because it will inevitably cause crashes after process death in production. viewPagerAdapter.addFragment()是一种反模式,因为它在生产中进程死亡后不可避免地会导致崩溃。

The correct way to implement a regular FragmentPagerAdapter is:实现常规 FragmentPagerAdapter 的正确方法是:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    public ViewPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        if(position == 0) return new RulesFragment();
        if(position == 1) return new TreeFragment();
        if(position == 2) return new PredictionFragment();

        throw new IllegalStateException("Unexpected position " + position);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if(position == 0) return "TREE RULES";
        if(position == 1) return "REGRESSION TREE";
        if(position == 2) return "PREDICTION";
      
        throw new IllegalStateException("Unexpected position " + position);
    }
}

To get a reference to a Fragment created by a ViewPager, use the following findFragmentByTag scheme:要获取对 ViewPager 创建的 Fragment 的引用,请使用以下findFragmentByTag方案:

Fragment fragment = supportFragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition)

To pass properties as a Bundle argument to the Fragment, it has to be passed to the instance created inside getItem() .要将属性作为 Bundle 参数传递给 Fragment,必须将其传递给在getItem()创建的实例。

Try this尝试这个

this.getArguments();

Code snippet代码片段

final Bundle args = this.getArguments();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM