为什么我的 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,如果它已经被实例化,你只需要返回一个引用。
不要在适配器中维护您自己对片段的引用,因为这些引用可以在不更新这些引用的情况下被您的适配器换出。
我正在尝试将数据从我的 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,如果它已经被实例化,你只需要返回一个引用。
不要在适配器中维护您自己对片段的引用,因为这些引用可以在不更新这些引用的情况下被您的适配器换出。