为什么我的 Fragment 没有实例化? Activity 与 Fragments 交流

Why is my Fragment not instantiated ? Activity to Fragments communication

我正在尝试将数据从我的 Activity(从 Firebase 获取数据)发送到另一个片段。它仅在我更改 Firebase 上的数据时有效,但在创建 Activity 时他第一次尝试时无效。第一次尝试时,方法 passDataToInfoFragment 和 passDataToRanklistFragment 中的片段始终为 NULL。我不知道为什么,所以我需要你的帮助。

GroupDetailFragmentCommunication:

public interface GroupDetailFragmentCommunication {
    public void passDataToInfoFragment(PublicGroup group);
    public void passDataToRanklistFragment(PublicGroup group);
}

GroupDetailActivity:

public class GroupDetailActivity extends AppCompatActivity implements GroupDetailFragmentCommunication{

    private FirebaseAuth auth;
    private FirebaseDatabase database;
    private DatabaseReference reference;
    private GroupDetailPagerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_detail);
        this.initFirebase();
        this.setUpToolbar();
        this.setUpTabLayout();
        this.getPublicGroup();
    }

    public void initFirebase() {
        auth = FirebaseAuth.getInstance();
        database = FirebaseDatabase.getInstance();
        reference = database.getReference();
    }

    public void setUpToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("Details");
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void setUpTabLayout() {
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        ArrayList<String> tabs = new ArrayList<>();
        tabs.add("Info");
        tabs.add("Rank");

        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        this.adapter = new GroupDetailPagerAdapter(getSupportFragmentManager(), tabs);
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
    }

    public void getPublicGroup() {
            reference.child("groups").child("public").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                PublicGroup pg = snapshot.getValue(PublicGroup.class);
                if (pg != null) {
                    pg.setKey(snapshot.getKey());
                    passDataToInfoFragment(pg);
                    passDataToRanklistFragment(pg);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            
            }
        });
    }


     @Override
    public void passDataToInfoFragment(PublicGroup group) {
        InfoFragment fragment = (InfoFragment) this.adapter.getFragment(0);
        if (fragment != null) {
            fragment.fragmentCommunication(group);
        } else {
            Log.i("Bla", "Fragment 1 is not instantiated");
        }
    }
s
    @Override
    public void passDataToRanklistFragment(PublicGroup group) {
        RanklistFragment fragment = (RanklistFragment) this.adapter.getFragment(1);
        if (fragment != null) {
            fragment.fragmentCommunication(group);
        } else {
            Log.i("Bla", "Fragment 2 is not instantiated");
        }
    }


}

GroupDetailPagerAdapter:

public class GroupDetailPagerAdapter extends FragmentStatePagerAdapter {
    private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    private ArrayList<String> tabHeader;

    public GroupDetailPagerAdapter(FragmentManager fm, ArrayList<String> tabHeader) {
        super(fm);
        this.tabHeader = tabHeader;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                Fragment infoTab = new InfoFragment();
                return infoTab;
            case 1:
                Fragment ranklistTab = new RanklistFragment();
                return ranklistTab;
            default:
                return null;
        }
    }

    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getFragment(int position) {
        return registeredFragments.get(position);
    }

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

快速浏览了您的代码后,我有一些怀疑:

  • 您是否尝试过设置断点 getPublicGroup() -> onDataChange(DataSnapshot snapshot) 方法?如果 pg 为空,则不会调用您的 "passing"-方法。

如果不是这种情况,则可能是当您在 [=17] 中调用 this.getPublicGroup() 时您的片段未完全实例化=]父 activity.

的 onCreate()
  • 您可以尝试将此行移动到您父 activity 的 onResume() 方法中,这有帮助吗?

要从您的适配器获取片段实例,请调用 instantiateItem 而不是 getFragment(在您的 passData... 方法中)。

如果您调用 instantiateItem,您将获得适配器正在引用的片段。不要担心多次调用 instantiateItem,如果它已经被实例化,你只需要返回一个引用。

不要在适配器中维护您自己对片段的引用,因为这些引用可以在不更新这些引用的情况下被您的适配器换出。