为什么我的片段没有实例化?活动碎片通信

问题描述:

我想从我的活动(从Firebase获取数据)发送数据到另一个碎片。它只在我更改Firebase上的数据时才有效,但不会在创建活动时进行第一次尝试。在第一次尝试时,方法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); 
 
    } 
 
}

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

如果您调用instantiateItem,则会得到该适配器引用的片段。不要担心多次调用instantiateItem,如果它已经实例化,你只需要返回一个参考。

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

+1

Thx为你的帮助,现在它工作! –

在你的代码,我看一眼之后有一些怀疑:

  • 你有没有尝试设置一个断点getPublicGroup() - > onDataChange( DataSnapshot快照)方法?如果为空,那么您的“传递”方法将不会被调用。

如果不是这种情况下,它可能是,当你调用this.getPublicGroup()的onCreate()的父活动的您的片段不完全实例化的情况。

  • 你可以尝试这条线移动到父活动的的onResume()方法来代替,这是否帮助?
+0

传递方法被调用,所以pg是!= null。试图将this.getPublicGroup()移入onResume,仍然是一样的问题。 Log.i(“Bla”,“片段1未实例化”);和Log.i(“Bla”,“Fragment 2 is not instantiated”);被叫 –