1

我想從我的活動(從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); 
 
    } 
 
}

回答

0

要從適配器中獲取片段實例,請調用instantiateItem而不是getFragment(在您的passData ...方法中)。

如果您調用instantiateItem,則會得到該適配器引用的片段。不要擔心多次調用instantiateItem,如果它已經實例化,你只需要返回一個參考。

不要在適配器中維護您自己對碎片的引用,因爲這些碎片可以被適配器換出,而不會更新這些引用。

+1

Thx爲你的幫助,現在它工作! –

1

在你的代碼,我看一眼之後有一些懷疑:

  • 你有沒有嘗試設置一個斷點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」);被叫 –