我正在尝试使用findFragmentById()
获取Fragment引用,但它总是返回一个null对象。我使用了FragmentPagerAdapter
并添加了OnPageChangeListener
因此,每当我滚动到特定片段时,请说FragmentB
,就应该触发FragmentB
的方法。
我有以下代码:
mPager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (position == 1) {
FragmentB fb = (FragmentB) getSupportFragmentManager().findFragmentById(R.id.fragment_b);
fb.refreshList();
//fb is always null
Toast.makeText(MainActivity.this,"Scrolled", Toast.LENGTH_SHORT).show();
//Toast is working fine
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2){}
@Override
public void onPageScrollStateChanged(int arg0){}
});
答案 0 :(得分:4)
请改为:
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
PagerAdapter pagerAdapter = (PagerAdapter) mPager.getAdapter();
if (position == 1) {
FragmentB fragmentB = (FragmentB)pagerAdapter.getItem(position);
fragmentB.refreshList();
}
}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
});
findFragmentById
的问题无意以这种方式使用:
在从XML中膨胀时查找由给定ID标识的片段,或者在事务中添加时查找容器ID。这首先搜索当前添加到经理活动中的片段;如果没有找到这样的片段,则搜索当前在与该ID相关联的后栈上的所有片段。
你应该调用它来获取片段容器中的哪个片段(例如,如果你正在使用导航抽屉,并且想知道哪个片段在视口中),那么你正在使用{{1它包含多个片段。
我希望,这有帮助。
答案 1 :(得分:2)
findFragmentById()
将始终返回null,因为您无法设置片段编码的ID!
如果您对此感兴趣,那么您的代码可能会在活动的xml文件中显示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/my_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.mypackage.MyFragment"/>
</LinearLayout>
这样,使用FragmentManager
在findFragmentById()
中查找片段会返回MyFragment
的正确实例。
findFragmentById()
是一种在FragmentManager中查找片段的方式,但在findFragmentByTag()
中还有另一种方式。
在您的情况下,您最有可能通过以下方法在PagerAdapter
的实例中设置这些片段:
@Override
public Fragment getItem(int position) {}
现在有很多示例和答案鼓励您使用一些反射来从FragmentManager中获取片段。 Android会自动为每个片段生成一个标记,您可以使用以下方法获取此名称:
private static String getFragmentName(int viewId, int id) {
return "android:switcher:" + viewId + ":" + id;
}
然后你可以构建一个getter方法来获取这样的片段:
public Fragment getFragmentForPosition(int position) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(getFragmentName(mViewPager.getId(), getItemId(position)));
return fragment; // May be null if the fragment is not found. Handle that case too wherever you call this method.
}
其中viewId
是ViewPager
和id
的xml文件中的ID,可以在适配器getItemId(position)
的任何位置获取。
这可行,但由于这里使用的反射,这是一个丑陋的解决方案。
这是一个非常简单但难看的解决方案,如果Android团队没有改变他们生成标签的逻辑,那么该解决方案应该有效:)
请参阅this SO响应以获取其他可能解决方案的列表。