我刚刚将旧的Android项目从Eclipse切换到Android Studio,在此过程中,我从旧的支持库版本19.0.1
更新为22.2.0
。在此之后,我在以前的代码中遇到了一些错误。我在其间下载了所有SDK并检查了错误最初发挥作用的位置,它似乎在版本21.1.0
及更高版本中。我在release notes查看了该版本,但找不到任何有趣的内容。
我的错误是我在这里得到NullPointerException
。请注意,此方法是Activity
的一部分,而不是父Fragment
。
public synchronized void onRecipesFiltered(ArrayList<Recipe> filteredRecipes)
{
FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment)
getSupportFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment);
// filteredRecipesListFragment becomes null
filteredRecipesListFragment.onRecipesFiltered(filteredRecipes);
}
我到达的Fragment
是ListFragment
,它是XML文件的一部分,在应用启动时会膨胀。在通货膨胀期间似乎将ListFragment
添加到父FragmentManager
内的Fragment
内。这可能是我在获取FragmentManager
的{{1}}时获得nullpointer的原因。因此,我的问题是:
如何获取Activity
中的ListFragment
?是否有必要保留对父Activity
的引用,以便通过其Fragment
获取ListFragment
?在FragmentManager
中返回Fragment
时父亲new MyFragment()
被夸大了,因此在FragmentPagerAdapter#getItem()
中获得正确的引用更加棘手。
还有一件事需要注意:我看到一些消息告诉我应该更新为Activity
,我做了(JDK 1.7
)。我不记得我做了什么,但在&#34;外部图书馆&#34;我看到OpenJDK 1.7
。不确定这是否重要。
答案 0 :(得分:1)
我按照this回答解决了这个问题。似乎不可能以一种漂亮的方式从Fragment
获取ViewPager
,因此它们必须在创建后保留为引用,并在需要时提取。
我在这里复制答案的主要代码,以防万一。主要想法是将Fragment
保留在SparseArray
中,以便在需要时获取它们。必须在创建之后/删除之前插入和删除它们。
public class MyPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return ...;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(...);
}
@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 getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
执行此操作后,我可以使用getChildFragmentManager()
将我的方法重写为以下内容,如@Skizo所述:
public synchronized void onRecipesFiltered(ArrayList<Recipe> filteredRecipes)
{
MyPagerAdapter myPagerAdapter = (MyPagerAdapter) mMyViewPager.getAdapter();
FilteredRecipesFragment filteredRecipesFragment = (FilteredRecipesFragment)
myPagerAdapter.getRegisteredFragment(PagerConstants.PAGE_FILTER_RECIPES);
if (filteredRecipesFragment == null)
{
// Fragments that has not yet been instantiated will be returned as null. Cannot do anything about it.
// Should be fairly unlikely. See:
// https://stackoverflow.com/a/15261142/1139324
return;
}
FilteredRecipesListFragment listFragment = (FilteredRecipesListFragment)
filteredRecipesFragment.getChildFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment);
listFragment.onRecipesFiltered(filteredRecipes);
}
答案 1 :(得分:0)
尝试替换:
FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment)
getSupportFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment);
到:
FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment)
getChildFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment);
详细了解getChildFragmentManager() documentation
上的getChildFragmentManager()